> ## Documentation Index
> Fetch the complete documentation index at: https://docs.grainql.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Shopify

> Install the Grain Tag in your Shopify theme and track cart, checkout, and purchase events.

This page adds the Grain Tag to the `theme.liquid` file of your Shopify theme. Then it adds events
for product views, cart additions, checkouts, purchases, and searches. It takes about 10 minutes.

## Before you start

You need three things:

* Admin access to your Shopify store.
* Your tenant alias from the [dashboard](https://grainql.com/dashboard). It is the alias shown at
  the top of the dashboard, not the UUID.
* 10 minutes.

<Warning>
  Duplicate your theme before you edit code. Go to **Themes**, then **Actions**, then **Duplicate**.
  If an edit breaks the theme, you can publish the copy.
</Warning>

## 1. Open the theme code

1. Log in to [Shopify admin](https://admin.shopify.com).
2. Click **Online Store**, then **Themes**.
3. Find your active theme. It has the "Current theme" badge.
4. Click **Actions**, then **Edit code**.

## 2. Edit theme.liquid

1. In the file list, open the **Layout** folder.
2. Click **theme.liquid**.
3. Find the `</head>` tag. Use Ctrl+F or Cmd+F to search.
4. Add this code directly before `</head>`:

```html theme={null}
<script src="https://tag.grainql.com/v4/your-tenant-id.js"></script>
<script>
  GrainTag.track('page_context', {
    page_type: '{{ template }}',
    shop: '{{ shop.name }}',
    currency: '{{ shop.currency }}'
  });
</script>
```

Replace `your-tenant-id` with your tenant alias.

`{{ template }}`, `{{ shop.name }}`, and `{{ shop.currency }}` are Liquid variables. Shopify
replaces them with the real values when it serves the page.

## 3. Save

Click **Save** (top right). Shopify shows a confirmation message. The Grain Tag now records page
views, clicks, and scroll depth on every page of the store. Read
[Automatic tracking](/core/automatic-tracking).

## 4. Track e-commerce events

Each snippet in this step sends one event with `GrainTag.track`. If a snippet runs before the
script is ready, the Grain Tag queues the event and sends it later.

### Add to cart

In `theme.liquid`, add this code directly before `</body>`:

```html theme={null}
<script>
  document.addEventListener('DOMContentLoaded', function() {
    const cartForms = document.querySelectorAll('form[action*="/cart/add"]');

    cartForms.forEach(function(form) {
      form.addEventListener('submit', function() {
        const variantId = form.querySelector('[name="id"]')?.value;
        const quantity = form.querySelector('[name="quantity"]')?.value || 1;

        GrainTag.track('product_added_to_cart', {
          variant_id: variantId,
          quantity: parseInt(quantity)
        });
      });
    });
  });
</script>
```

### Checkout started

Add this code after the add-to-cart snippet:

```html theme={null}
<script>
  document.addEventListener('DOMContentLoaded', function() {
    const checkoutButtons = document.querySelectorAll('button[name="checkout"], a[href*="/checkout"]');

    checkoutButtons.forEach(function(button) {
      button.addEventListener('click', function() {
        GrainTag.track('checkout_started', {
          page: window.location.pathname
        });
      });
    });
  });
</script>
```

### Purchases

The order status page is not part of the theme. Go to **Settings**, then **Checkout**, then
**Order status page**, then **Additional scripts**, and add this code:

```html theme={null}
<script src="https://tag.grainql.com/v4/your-tenant-id.js"></script>
<script>
  GrainTag.track('purchase_completed', {
    order_id: '{{ checkout.order_id }}',
    total: {{ checkout.total_price | money_without_currency }},
    currency: '{{ checkout.currency }}',
    discount: {{ checkout.total_discounts | money_without_currency }},
    shipping: {{ checkout.shipping_price | money_without_currency }}
  });
</script>
```

<Note>
  Order status scripts are available in **Settings**, then **Checkout**, on Shopify Plus or certain
  themes.
</Note>

### Product views

Add this code in `theme.liquid`. The `{% if %}` tag limits it to product pages:

```html theme={null}
{% if template == 'product' %}
<script>
  GrainTag.track('product_viewed', {
    product_id: '{{ product.id }}',
    product_title: '{{ product.title }}',
    price: {{ product.price | money_without_currency }},
    vendor: '{{ product.vendor }}',
    available: {{ product.available }}
  });
</script>
{% endif %}
```

### Searches

Add this code in `theme.liquid`. It runs on the search results page only:

```html theme={null}
{% if template == 'search' %}
<script>
  GrainTag.track('search_performed', {
    query: '{{ search.terms }}',
    results_count: {{ search.results.size }}
  });
</script>
{% endif %}
```

Read [Name events](/core/event-naming) for the naming convention.

## 5. Test the installation

1. Open your store in a private (incognito) window.
2. Open a product page, add the product to the cart, and go to checkout.
3. Open the browser console (F12, then **Console**).
4. Type `window.GrainTag`. The console shows the `GrainTag` object.
5. Open the [dashboard](https://grainql.com/dashboard) and make sure that the events are there.

## Troubleshooting

| Symptom | Cause | What to do |
| - | - | - |
| The code does not run | The tenant alias in the script URL has a typo | Compare the alias with the one at the top of the dashboard. |
| The code does not run | The browser holds an old copy of the page | Reload without the cache: Ctrl+Shift+R or Cmd+Shift+R. |
| The code does not run | A script on the page fails | Open the console (F12) and read the errors. |
| The code does not run | The code is not before `</head>` or `</body>` | Move the code to the position that the step names. |
| Events are not in the dashboard | Events arrive after a delay of up to 30 seconds | Wait 30 seconds, then reload the dashboard. |
| Events are not in the dashboard | The theme file is not saved | Open `theme.liquid` and click **Save**. |
| Events are not in the dashboard | The script did not load | Type `window.GrainTag` in the console. The console must show the `GrainTag` object. |
| The theme is broken | A Liquid tag (`{{ }}` or `{% %}`) was deleted during the edit | Make sure that every Liquid tag is intact. To revert, go to **Themes**, then **Actions**, then **Unpublish**, and publish your backup. |

Read [Troubleshooting](/troubleshooting) for cases that are not specific to Shopify.

## Next steps

<CardGroup cols={2}>
  <Card title="Trackers" icon="crosshairs" href="/features/trackers">
    Track clicks on specific elements from the dashboard, without code.
  </Card>

  <Card title="Heatmaps" icon="fire" href="/features/heatmaps">
    See where visitors click and how far they scroll.
  </Card>

  <Card title="Tracks" icon="route" href="/features/tracks">
    Build funnels from landing page to purchase.
  </Card>

  <Card title="Privacy and consent" icon="shield" href="/essentials/privacy-and-compliance">
    What Grain stores, cookieless mode, and consent modes.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.