> For the complete documentation index, see [llms.txt](https://docs.adpage.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.adpage.io/integrations-websites/shopify.md).

# Shopify

How to set up server-side tagging for a Shopify webhop

***

## Setting up server-side tagging for Shopify

This article walks you through the full setup of server-side tagging on a Shopify store: generating your Google Tag Manager templates, importing them, filling in your IDs, testing them, and finally removing the old tracking connections that Shopify made for you.

### Before you start

This article picks up where **Getting Started** leaves off. Make sure all of the steps in the [Setup AdPage container](/getting-started/setup-adpage-container.md) article have been followed. Which means that:

* [ ] Your **AdPage container** is created.
* [ ] Your AdPage container is **connected to your GTM server container**.
* [ ] The **CNAME record** is added in your DNS settings, so tagging runs on your own (sub)domain.
* [ ] The **AdPage Shopify app, customer events pixel & webhook** is installed in your store.

{% hint style="warning" %}
If one of these steps is still open, finish it first. Everything below assumes your server container is reachable on your own domain and that the Shopify app is pushing data into the dataLayer.
{% endhint %}

***

### Step 1: Generate your templates in the Template Library

You do not have to build your tags, triggers and variables by hand. AdPage's Template Library generates a complete, tested Google Tag Manager setup for Shopify for you.

1. Go to [data.adpage.io/template-library](https://data.adpage.io/template-library).
2. Select the marketing platforms you want to send data to, for example Google Ads, Meta Ads, TikTok Ads, LinkedIn Ads or Pinterest Ads.
3. Select the Consent Management Platform you use on your Shopify webshop.
4. Generate the templates. You get **two JSON files**: one for your GTM **web** container and one for your GTM **server** container.
5. Download both files and keep them handy.

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2Fo4nPmZrjh5NFMGAYOnPp%2Fimage.png?alt=media&amp;token=a8b98f2d-df97-4c6a-9a20-c91350247029" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Only select the platforms you actually use. Every platform you add creates extra tags and constant variables that you will need to fill in later.
{% endhint %}

***

### Step 2: Import the web container template

1. Open your **GTM web container**.
2. Go to **Admin** and click **Import Container**.
3. Select the **web** JSON file you downloaded.
4. Choose a workspace.&#x20;
   * If you have unpublished changes in your default workspace, we recommend importing into a **new workspace** so your import stays separate from any other work in progress.
5. Choose the import option:
   * **Merge and rename conflicting tags, triggers and variables** for a container that already contains a setup. Nothing existing gets removed.
   * **Overwrite** only for a brand new, empty container.
6. Check the preview of the changes that GTM shows you, then click **Confirm**.

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2F3CKvxX1mSb1O2JBpcE4Q%2Fimage.png?alt=media&amp;token=ee12042d-41d9-4406-95f9-9e2eaf8d3bc1" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
Do not publish your GTM web container yet. The tags in the import are still missing your IDs, which you fill in at step 4.
{% endhint %}

***

### Step 3: Import the server container template

Repeat the same steps in your **GTM server container** with the **server** JSON file.

1. Open your **GTM server container**.
2. Go to **Admin** and click **Import Container**.
3. Select the **server** JSON file.
4. Import into a new workspace and choose **Merge and rename conflicting tags, triggers and variables**.
5. Check the preview and click **Confirm**.
6. Go to **Clients** and check if an extra GA4 client has been set up. If so, delete the imported GA4 client.

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2FyhuHijhZUYGKSi2cG86j%2Fimage.png?alt=media&amp;token=fbe37ee9-0cec-4291-8c7d-b9f5569cb1d6" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
Do not publish your GTM server container yet. The tags in the import are still missing your IDs and tokens, which you fill in at step 4.
{% endhint %}

***

### Step 4: Fill in the constant variables

Both templates are built around **constant variables**. All IDs, tokens and settings live in one place, so you never have to open individual tags to change something.

1. In your GTM web container, go to **Variables**.
2. Open every constant variable, which you can recognize by the "@" in the name. Fill in the correct value per variable. See the table below to know what ID or Token you have to fill in.
3. Save each variable.
4. In your GTM server container, go to **Variables**.
5. Open every constant variable, which you can recognize by the "@" in the name. Fill in the correct value per variable. See the table below to know what ID or Token you have to fill in.
6. Save each variable.

Depending on the platforms you selected, you will typically fill in:

<table><thead><tr><th width="118">Container</th><th width="240">Variable</th><th>Value</th></tr></thead><tbody><tr><td>Web</td><td>Server Container URL</td><td>The tagging domain from your CNAME record, for example: <code>https://tagging.domain.com</code></td></tr><tr><td>Web</td><td>GA4 Measurement ID</td><td>Your GA4 property's Measurement ID: <br><code>G-XXXXXXXXXX</code></td></tr><tr><td>Web</td><td><a href="/integrations-marketingtools/meta-ads/where-to-find-the-meta-pixel-id-and-the-meta-api-token.md">Meta Pixel ID</a></td><td>Your Pixel ID from Meta Events Manager</td></tr><tr><td>Web</td><td><a href="/integrations-marketingtools/tiktok-ads/where-to-find-the-tiktok-pixel-id-and-the-tiktok-api-token.md">TikTok Pixel ID</a></td><td>Your Pixel ID from TikTok Events Manager</td></tr><tr><td>Web</td><td><a href="/integrations-marketingtools/pinterest-ads/where-to-find-the-pinterest-tag-id-advertiser-id-and-api-token.md">Pinterest Tag ID</a></td><td>Your Pinterest Tag ID, found in the Tag Manager of your Pinterest Ads Account</td></tr><tr><td>Web</td><td><a href="/integrations-marketingtools/linkedin-ads/where-to-find-the-linkedin-partner-id-conversion-ids-and-api-token.md">LinkedIn Partner ID</a></td><td>Your LinkedIn Partner ID, found in the Signals Manager of your LinkedIn Ads Account</td></tr><tr><td>Web</td><td>Cookiebot Domain Group ID</td><td>The Domain Group ID from your Cookiebot account</td></tr><tr><td>Server</td><td>GA4 Measurement ID</td><td>Your GA4 property's Measurement ID: <br><code>G-XXXXXXXXXX</code></td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/meta-ads/where-to-find-the-meta-pixel-id-and-the-meta-api-token.md">Meta Pixel ID</a></td><td>Your Pixel ID from Meta Events Manager</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/meta-ads/where-to-find-the-meta-pixel-id-and-the-meta-api-token.md">Meta API Ttoken</a></td><td>The API Token of your Pixel from Meta Events Manager</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/tiktok-ads/where-to-find-the-tiktok-pixel-id-and-the-tiktok-api-token.md">TikTok Pixel ID</a></td><td>Your Pixel ID from TikTok Events Manager</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/tiktok-ads/where-to-find-the-tiktok-pixel-id-and-the-tiktok-api-token.md">TikTok API Token</a></td><td>The API Token of your Pixel from TikTok Events Manager</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/google-ads/where-to-find-the-google-ads-conversion-id-and-conversion-labels.md">Google Ads Conversion ID</a></td><td>Your Google Ads Conversion ID: <br><code>AW-XXXXXXXXXX</code> minus the <code>AW-</code> part</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/google-ads/where-to-find-the-google-ads-conversion-id-and-conversion-labels.md">Google Ads Conversion Labels</a></td><td>Create new <code>purchase</code>, <code>add_to_cart</code>, and <code>begin_checkout</code> conversions in Google Ads. Once set up, you can find their Conversion Labels.</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/pinterest-ads/where-to-find-the-pinterest-tag-id-advertiser-id-and-api-token.md">Pinterest Advertiser ID</a></td><td>The Advertiser ID from your Ad Account. This ID usually starts with 549.</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/pinterest-ads/where-to-find-the-pinterest-tag-id-advertiser-id-and-api-token.md">Pinterest API Token</a></td><td>The API Token found in your Conversions API settings of your Pinterest Business Account.</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/linkedin-ads/where-to-find-the-linkedin-partner-id-conversion-ids-and-api-token.md">LinkedIn API Token</a></td><td>The API Token which you can generate in your LinkedIn Campaign Manager in the Sources.</td></tr><tr><td>Server</td><td><a href="/integrations-marketingtools/linkedin-ads/where-to-find-the-linkedin-partner-id-conversion-ids-and-api-token.md">LinkedIn Conversion IDs</a></td><td>Create new <code>purchase</code>, <code>add_to_cart</code>, and <code>begin_checkout</code> conversions in LinkedIn Ads. Once set up, you can find their Conversion IDs in the URL of the conversion.</td></tr></tbody></table>

{% hint style="info" %}
Never leave a constant variable empty. An empty ID means tags fire without a destination, which shows up as missing conversions or failed outgoing requests later on.
{% endhint %}

***

### Step 5: Test in preview mode

You have just imported container templates with complete tracking for GA4 and the marketing platforms you selected. That means everything you need is now present in your GTM containers, and anything that was already there for the same purpose is a duplicate.

#### **Disable your old tags first**

Go through the tags in your web container and pause or delete every tag that measures something your new setup now handles. In practice this is your old GA4 configuration tag, all GA4 event tags for e-commerce steps such as `add_to_cart` and `purchase`, your Meta Pixel tags, your Google Ads remarketing tags, and any custom HTML tags that send data to a platform directly.&#x20;

If you are not sure whether you will need an old tag later, pause it instead of deleting it. You can always remove it in a later version once the new setup has proven itself. Old triggers and variables can stay, they do nothing on their own.

Skip this and preview mode will show two of everything, and after publishing your conversions will be counted twice.

#### Test both containers

1. Open the **Preview mode** in your GTM web container and fill in the URL of your webshop.
2. Open the **Preview mode** in your GTM server container as well, so you can follow the same hits arriving server-side.
3. Walk through the customer journey and check that each step fires once, with the right e-commerce parameters:
   * `page_view`
   * `view_item_list`
   * `view_item`
   * `add_to_cart`
   * `view_cart`
   * `remove_from_cart`
4. For every event, check in the **server** container that the GA4 event request arrives and that your platform tags fire and return a successful response.

{% hint style="warning" %}
If the GA4 event requests don't arrive on the server container's preview mode, it means that the server\_container\_url parameter in the Google Tag gets overwritten somewhere. Check these three options:

* Check if there is another Google Tag active on your GTM web container with the same GA4 Measurement ID. If there is, pause that tag.
* Check if the Google & YouTube App in Shopify has a direct connection set up with the GA4 property you are setting up server-side tagging for. If so, disconnect this connection.
* Check if the Google & YouTube App in Shopify has the 'conversion measurement' option set to 'On'. If so, set the conversion measurement option to 'Off'.
  {% endhint %}

#### Debugging the Shopify checkout

Shopify loads the checkout inside an iframe, which means you cannot debug it directly in Google Tag Manager's preview mode. Your GTM web container preview mode and a dataLayer checker extension will not show you the steps from `begin_checkout` up to and including `purchase`.

To test those steps anyway, install the [DataLayer Checker Plus](https://chromewebstore.google.com/detail/datalayer-checker-plus/blglfmihmnbhfgfbomofeljmididgfhe) extension.

Besides checking the dataLayer of a website, the extension has two extra options behind the gear icon:

* The first option lets you inspect the dataLayer inside the extension.
* The second option injects the standard `<head>` script of your GTM web container. With that script injected, you can debug the entire checkout in both your GTM web container and your GTM server container again.

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2FOwy7oqioDhtn2AP1nvyt%2Fimage.png?alt=media&amp;token=4dc5dfd9-ea96-449b-b8d4-601d5aa0fc04" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="info" %}
Remember to switch both options off when you are done debugging. If you leave them on, that `<head>` code gets injected on every page you visit.
{% endhint %}

***

### Step 6: Publish both containers

Once everything looks right in preview modes, publish both GTM containers.

Use a clear version name and description, for example "AdPage server-side tagging", so you can roll back if needed.

Your data now runs through your server container. Any connection that Shopify still maintains directly with an advertising platform will send the same events a second time, which leads to duplicated conversions and inflated revenue in your reports.

Go through the platforms below and disconnect what you no longer need.

#### Google Analytics 4

1. Open the **YouTube & Google** app in Shopify and navigate to the settings.
2. Disconnect the Google Analytics property if you see that one is still connected.
3. Make sure the **Conversion measurement** option is switched off.

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2FkZH2umQpv5dfokhevgMR%2Fimage.png?alt=media&amp;token=027fb520-519b-4c3c-b44f-048e1b13d683" alt=""><figcaption></figcaption></figure>

#### Meta Ads

1. Open the **Facebook & Instagram** app in Shopify and navigate to the settings.
2. Ensure the **Data Sharing** option is switched off.

{% hint style="info" %}
You'll need access to the Facebook Pixel to be able to switch off this option
{% endhint %}

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2FX13srrLuRND5mF6rq5Xk%2Fimage.png?alt=media&amp;token=857391bc-6c5d-4162-ac98-7e6a5702e9d4" alt=""><figcaption></figcaption></figure>

#### TikTok Ads

1. Open the **TikTok** app in Shopify and navigate to the settings.
2. Go to the **Data Sharing** settings.
3. Click **Disconnect** behind the pixel.

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2FPzV7IYfMTSZRv5yEEBvR%2Fimage.png?alt=media&amp;token=bbfe5cce-18bc-4f1c-b9f7-5de6906680e4" alt="" width="563"><figcaption></figcaption></figure>

#### Pinterest Ads

1. Open the **Pinterest** app in Shopify and navigate to the marketing settings.
2. Disconnect the Pinterest Tag, so you no longer share data directly with Pinterest.

<figure><img src="https://1274044937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA65KwL1NwewlJbtCXsXd%2Fuploads%2FJsrQFxfsk2BL2DUMwkls%2Fimage.png?alt=media&amp;token=2516526e-3f20-49a7-b431-df6e63078515" alt="" width="563"><figcaption></figcaption></figure>

#### Check your theme and custom pixels

Finally, check the theme code and Shopify's **Customer events** (custom pixels) for hardcoded tracking scripts that were added manually in the past. Remove what is now handled by your server container.

{% hint style="info" %}
After publishing, compare your conversions for a few days against your shop's own order count. Numbers that are consistently too high are usually a sign that an old connection is still active somewhere.&#x20;
{% endhint %}

***

### Need help?

Still seeing missing events, duplicated conversions or unassigned traffic after following these steps? Reach out to our support team and we will take a look with you.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.adpage.io/integrations-websites/shopify.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
