> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.pandectes.io/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Google Consent Mode in a Shopify custom pixel (Google Tag Manager)

### Overview

Some stores load a Google Tag Manager (GTM) container from a **Shopify custom pixel** (**Settings > Customer events**) instead of, or as well as, from the storefront. This article shows how to apply Google Consent Mode Advanced to the tags that container fires.

With GTM there is very little code to write. Two lines at the top of the pixel hand the visitor's consent to the **Pandectes CMP** tag in your container, and the tag does the rest.

If you do not use GTM and load Google Analytics 4 or Google Ads directly with `gtag.js`, use [Google Consent Mode in a Shopify custom pixel (gtag.js)](/en/article/google-consent-mode-in-a-shopify-custom-pixel-gtagjs-egs4ti/) instead. Use one approach or the other for a Google property, never both.

### Before you start

* **The Pandectes CMP tag must be in your container.** Add it from the GTM Template Gallery, fire it on **Consent Initialization - All Pages**, and set the consent each tag needs. The steps are in [Integration with Google Tag Manager (GTM) - Official Pandectes Template](/en/article/integration-with-google-tag-manager-gtm-official-pandectes-template-6dbjz/).
* **Set up the storefront side first.** The pixel only covers what runs inside the pixel. Google tags on the storefront itself are set up as described in [How to set up Google Tag Manager with Pandectes](/en/article/how-to-set-up-google-tag-manager-with-pandectes-1w5g3hv/).
* **Check your plan.** Google Consent Mode and the Pandectes CMP tag work on the **Plus** plan and above.

### Why the pixel needs its own consent setup

A Shopify custom pixel runs in a sandboxed iframe with its own `window` and its own `dataLayer`. It is separate from the storefront page, and consent set in one is invisible to the other.

So a container loaded inside the pixel cannot see the consent that the storefront already has. The two lines below pass it in. Everything in this article applies **inside the pixel only**.

### The two lines

Put these at the **very beginning** of the custom pixel, before the GTM snippet and before anything else:

```javascript
window.pandectesPixelInit = init;
window.pandectesSubscribe = api.customerPrivacy.subscribe;
```

That is the whole consent setup. The Pandectes CMP tag in your container reads them, applies the right default consent state for the visitor, and updates it whenever the visitor changes their choice on the banner. You do not need to write `default` or `update` commands or keep a list of regions: the tag takes the policy from your banner settings.

Two placement rules:

* **The lines come first.** The tag reads them when the container starts. If the GTM snippet runs before them, there is nothing to read.
* **The lines go in the same pixel as the container.** Each custom pixel is its own sandbox. Setting them in one pixel does nothing for a container loaded in another.

### Advanced mode and the pixel permission

This setup gives you **Google Consent Mode Advanced**: the container loads on every page view, its tags send cookieless pings while consent is denied, and they switch to full measurement once consent is granted.

For that, the pixel must be allowed to run before consent. In Shopify Admin, go to **Settings > Customer events**, open your custom pixel, and under **Customer privacy** set **Permission** to **Not required**. If you set it to **Required**, Shopify holds the pixel back until the visitor accepts, the container never loads, and no cookieless pings are sent.

If you want **Basic mode** instead (nothing loads until consent is given), set **Permission** to **Required**, select the categories you need, and let Shopify hold the pixel back.

### The pixel code

1. In Shopify Admin, go to **Settings > Customer events** and click **Add custom pixel**.
2. Give the pixel a name and paste the code below.
3. Replace `GTM-XXXXXXX` with your container ID.
4. Add your own event subscriptions at the bottom.
5. Set the permission as described above, click **Save**, then **Connect**.

```javascript
/* Pandectes consent handover.
 * Keep these two lines at the very top, above the GTM snippet.
 * The Pandectes CMP tag in your container reads them. */
window.pandectesPixelInit = init;
window.pandectesSubscribe = api.customerPrivacy.subscribe;

/* START_MODIFY_FOR_YOUR_STORE */
const GTM_ID = "GTM-XXXXXXX"; // your container ID
/* END_MODIFY_FOR_YOUR_STORE */

/* Load the GTM container inside the pixel sandbox.
 * This dataLayer is not shared with the storefront or other pixels. */
window.dataLayer = window.dataLayer || [];

(function (w, d, s, l, i) {
  w[l] = w[l] || [];
  w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
  var f = d.getElementsByTagName(s)[0],
    j = d.createElement(s),
    dl = l != "dataLayer" ? "&l=" + l : "";
  j.async = true;
  j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
  f.parentNode.insertBefore(j, f);
})(window, document, "script", "dataLayer", GTM_ID);

/* YOUR EVENT SUBSCRIPTIONS GO HERE, IN THIS SAME PIXEL.
 *
 * The code above sets consent and loads the container. On its own it
 * pushes nothing to the dataLayer.
 *
 * The example below is sample code only, adapted from Shopify's GTM
 * tutorial. Adapt the events and fields to your own GTM triggers.
 * Shopify's original also pushes email, phone and address. Those are
 * left out on purpose: putting personal data in the dataLayer is a
 * privacy decision you need to make for your own store. */

// analytics.subscribe("checkout_completed", (event) => {
//   window.dataLayer.push({
//     event: "checkout_completed",
//     timestamp: event.timestamp,
//     id: event.id,
//     token: event.data?.checkout?.token,
//     url: event.context.document.location.href,
//     client_id: event.clientId,
//     orderId: event.data?.checkout?.order?.id,
//     currency: event.data?.checkout?.currencyCode,
//     subtotal: event.data?.checkout?.subtotalPrice?.amount,
//     shipping: event.data?.checkout?.shippingLine?.price?.amount,
//     value: event.data?.checkout?.totalPrice?.amount,
//     tax: event.data?.checkout?.totalTax?.amount,
//   });
// });
```

Each event you push needs a matching **Custom Event** trigger in GTM with exactly the same name as the `event` key (`checkout_completed` in the sample).

||| **Pandectes provides the consent layer only.** The two lines set the consent state and nothing else. Which events you push, what data they carry, how your GTM tags and triggers are set up, and whether your Google Analytics or Google Ads reporting is accurate are your responsibility. Pandectes does not support or verify the tracking built on top of this code.

### Every pixel that loads a container needs the two lines

You cannot put the two lines in one custom pixel and load the container in another. Each pixel is a separate sandbox. A container loaded in a pixel without the two lines has no consent state, and its tags fire under Google's defaults with no warning.

The same goes for your event subscriptions: they must be in the same pixel, below the GTM snippet.

### Check that it works

#### Tag Assistant and GTM Preview cannot see the pixel

Neither Google Tag Assistant nor GTM **Preview** mode connects to a container that runs inside the pixel sandbox. They inspect the storefront page only, so they report nothing (or only the storefront's own tags) even when the pixel works correctly. This is expected and is not an error.

#### Check the dataLayer in the pixel's frame

1. Open Chrome DevTools and go to the **Console** tab.
2. In the console toolbar, open the frame dropdown (it normally shows `top`) and select the pixel's sandbox frame (its name starts with `web-pixel`). Shopify creates one frame per custom pixel, so pick the right one if you have several.
3. Run the checks below.

In the `top` frame, `dataLayer` is the storefront's data layer, which tells you nothing about the pixel.

* **Are the two lines set?** `window.pandectesPixelInit` and `window.pandectesSubscribe` should both be defined.
* **Does consent come before the tags?** In `dataLayer`, the consent entries must appear before your tags fire.
* **Does the pixel load before consent?** It must, for Advanced mode. If the container only appears after the visitor accepts, the pixel permission is set to **Required** and you are in Basic mode.
* **Do your events arrive?** Place a test order and check that the event appears in `dataLayer` with the name your GTM trigger expects.

### Common mistakes

| Mistake | What happens |
| --- | --- |
| The two lines are placed after the GTM snippet | The tag has nothing to read when the container starts. Tags fire under Google's defaults. |
| The two lines are in one pixel and the container in another | Separate sandboxes. The container has no consent state. |
| The Pandectes CMP tag is not in the container | The lines are set but nothing reads them. No consent mode in GTM. |
| Pixel **Permission** set to **Required** | Shopify holds the pixel until consent, so the container never loads before it. That is Basic mode, not Advanced. |
| Testing with Tag Assistant or GTM Preview | They cannot see the pixel sandbox and report nothing, even when everything works. |
| Reading `dataLayer` in the `top` frame | That is the storefront's data layer, not the pixel's. |
| No GTM **Custom Event** trigger for a pushed event | The event reaches the dataLayer, but no tag fires. |
| Pasting Shopify's sample event unchanged | Event names and fields that do not match your triggers, and personal data in the dataLayer. |
| The same property loaded from this pixel and from a gtag.js pixel | Duplicate hits and two competing consent states. |

### Settings this article does not cover

Settings such as `url_passthrough`, `ads_data_redaction`, `allow_enhanced_conversions` and `restricted_data_processing` are set in GTM (on the Pandectes CMP tag or on your own tags), not in the pixel.

Pandectes cannot advise on these. The right values depend on your Google Ads and Analytics accounts, the modelling you rely on, and your business's legal position. Discuss them with whoever manages your Google setup, or with your legal advisor where there is a privacy question.