Free guide
Google / Microsoft Consent mode & customer events on Shopify (100% GDPR)
This technical guide is aimed at Shopify users located in Europe and subject to the GDPR. It explains in detail how to integrate Google Consent Mode v2 & the new Microsoft Consent Mode in accordance with the GDPR by leveraging Shopify Customer Events (customer events) and the Web Pixels API.
Since Google & Microsoft updated their Consent Mode, a new requirement has emerged: ensure that Google/Microsoft tags (Analytics, Ads...) respect visitors' consent choices, without compromising data quality. In an environment like Shopify, this requires fine-tuned configuration, particularly because:
- Third-party scripts can no longer be executed without explicit consent in Europe
- The Shopify checkout is isolated from the storefront, which poses consent synchronization challenges.
- The installation of Custom Pixels has become the recommended standard, but remains poorly documented and scripts are sandboxed.
The aim of this guide is to provide you with a practical, technical and operational framework for:
- Correctly configure advanced Google Consent Mode v2 & Microsoft Consent Mode in your Shopify store
- Select the most suitable method according to the cookie banner used Pandectes, Cookiebot, CookieYes, etc.
- Guarantee GDPR compliance while maintaining the quality of marketing data (Analytics, Ads...).
The content is based on real-life tests, production feedback and customized scripts.
Ready to professionalize your consent management on Shopify? Follow the step-by-step guide 👇
Technical principles: Google / Microsoft Consent Mode and Shopify
Google / Microsoft Consent Mode: general operation
Google / Microsoft Consent Mode allows you to dynamically adapt the behavior of your tags (Analytics, Ads, etc.) according to visitors' consent choices. Two commands are used:
consent defaultapplied automatically on arrival at the site, before the user interacts with the bannerconsent updatetriggered when the visitor accepts or rejects certain categories of cookies
These commands transmit consent statuses for each type of storage: ad_storage, analytics_storage, functionality_storageetc. GTM tags can then condition their execution accordingly.
Shopify & Customer Events
Shopify now allows you to create Custom Pixels that run on storefront pages and capture interactions via Customer Events. These events replace the old tracking scripts injected directly into the theme or checkout.
Example of available standard events:
- cart_viewed
- checkout_completed
- checkout_shipping_info_submitted
- checkout_started
- collection_viewed
- page_viewed
- payment_info_submitted
- product_added_to_cart
- product_removed_from_cart
- product_viewed
- search_submitted
It is also possible to issue custom events such as custom_click for specific tracking needs.
🔐 Synchronize user consent in Shopify
Shopify exposes an API called Shopify.customerPrivacy which dynamically checks whether a user can be tracked or not, according to the choices he or she has expressed in the cookie banner.
📋 Consent object structure
{
"analyticsProcessingAllowed": boolean,
"marketingAllowed": boolean,
"preferencesProcessingAllowed": boolean,
"saleOfDataAllowed": boolean
}
✅ Useful functions available in JavaScript
window.Shopify.customerPrivacy.userCanBeTracked()- returnstrueif the user has given consent for both analytics and marketingwindow.Shopify.customerPrivacy.userDataCanBeSold()- returnstrueif the user has not explicitly refused the sale of his/her datawindow.Shopify.customerPrivacy.saleOfDataRegion()- returns the legal region detected for the visitor (ex:ca,us,eu)
These methods are invaluable for determining the logic behind the triggering of tags in your custom pixels, particularly on first visits or on checkout pages where certain banners fail to load.
A Well-designed Custom Pixel will leverage these APIs to push events into the dataLayer only after validating the availability of consent. This verification guarantees that your GTM tags will respect the user's choices.
🧰 Preparation: technical prerequisites
Before diving into the configuration of Google / Microsoft Consent Mode and Custom Pixels, it's essential to properly prepare your Shopify and GTM environment. This step helps avoid conflicts, duplicate tracking or unexpected tag behavior.
✅ What you need to have or check
- A Google Tag Manager account with an active Web container
- Access to Shopify Admin and the theme editor (code)
- A compatible cookie-banner system (see next section for options)
- Basic knowledge of Shopify Snippets, and javascript or a developer to assist you
🧹 Clean up old configurations
Many Shopify stores still have obsolete tracking traces. These elements must be removed before enabling clean consent management:
- Deactivate the Google & YouTube app if it is active and used only for conversions, otherwise deactivate conversion tracking only in the settings.
- Delete old GA or gtag.js scripts injected via Shopify's
Additional scriptsfield (Order status page) in /settings/checkout
- Remove any old systems in the theme that trigger GA or Ads calls without consent: TripleWhale (disable Sonaar), Voluum (disable integrations) ...
Google/Microsoft Consent Mode integration via any CMP on Shopify (Cookiebot, OneTrust, CookieYes...)
Contrary to what some suppliers claim, very few third-party CMPs automatically handle Google Consent Mode V2 or Microsoft Consent Mode correctly in Shopify.
And even less so taking into account Customer Events. Here's how to tie it all together neatly.
Conditions: your CMP must provide a cookie to read the consent status by category AND a synchronous API that directly returns the consent status by category. This guide has been tested mainly with Cookiebot.
CMP already taken care of in my script below
| CMP | Cookie detected | Consent detected via | Events listened to |
|---|---|---|---|
| Cookiebot | CookieConsent |
Regex (marketing:true, preferences:trueetc.) |
load, CookiebotOnAccept |
| CookieYes | cookieyes-consent |
Regex (advertisement:yes, performance:yesetc.) |
load, cookieyes_consent_update |
| OneTrust | OptanonConsent |
Regex on groups=C000X:1 |
load, OneTrustGroupsUpdated |
| CookieScript | CookieScriptConsent |
Regex on categories=["targeting", ...] |
load, CookieScriptCategory-strict |
| CookieFirst | cookiefirst-consent |
Regex ("performance":true, "advertising":trueetc.) |
load, cf_consent |
| 🛑 Axeptio | (n/a) | ❌ Requires asynchronous API via window._axcb.push() |
not supported in this script |
🛑 Axeptio is not included here because it requires an asynchronous API (
_axcb).
Step 1: Insert the CMP script into the theme
Go to Online Store > Themes > Edit code of the currently published theme
Then open theme.liquid. Look for the line:
<head>
And just below, insert:
{% render 'cookie-consent' %}
Next, create the snippet cookie-consent.liquid in the snippets folder containing your CMP script, for example:
▶️ Example with Cookiebot:
<script
id="Cookiebot"
src="https://consent.cookiebot.com/uc.js"
data-cbid="VOTRE-CBID-ICI"
type="text/javascript"
defer>
</script>
Step 2: Synchronize CMP consent → Shopify
In the same snippet cookie-consent.liquidAdd this code after your CMP's main script:
<script>
let lastSyncedConsent = null;
function syncConsentToShopify(consent) {
window.Shopify.loadFeatures([{ name: "consent-tracking-api", version: "0.1" }], function (error) {
if (error) return console.error("❌ Erreur chargement API Shopify");
const payload = {
analytics: consent?.statistics || false,
marketing: consent?.marketing || false,
preferences: consent?.preferences || false,
sale_of_data: consent?.sale_of_data || consent?.marketing || false,
};
window.Shopify.customerPrivacy.setTrackingConsent(payload, () => {
console.log("🟢 Consent Shopify synchronisé :", payload);
});
});
}
function publishConsentEvent(eventPayload) {
if (Shopify?.analytics?.publish) {
Shopify.analytics.publish("cookie_consent", eventPayload);
console.log("🔔 Event 'cookie_consent' publié via Shopify.analytics :", eventPayload);
} else {
console.warn("⚠️ Shopify.analytics.publish indisponible.");
}
}
function parseConsentByCMP() {
const cookieString = decodeURIComponent(document.cookie);
const match = (pattern) => new RegExp(pattern, "i").test(cookieString);
const consent = {
marketing:
match("marketing[:=]true") ||
match("advertising[:=]true") ||
match("C0004:1") || match("C0005:1") ||
match("targeting") ||
match("advertisement:yes"),
statistics:
match("statistics[:=]true") ||
match("performance[:=]true") ||
match("analytics[:=]true") ||
match("C0002:1") ||
match("performance") ||
match("analytics:yes"),
preferences:
match("preferences[:=]true") ||
match("functional[:=]true") ||
match("C0003:1") ||
match("functionality") ||
match("functional:yes"),
sale_of_data:
match("marketing[:=]true") ||
match("advertising[:=]true") ||
match("advertisement:yes") ||
match("C0004:1") || match("C0005:1")
};
// CMP auto-détecté
if (match("CookieConsent")) window.__detectedCMP = "Cookiebot";
else if (match("cookieyes-consent")) window.__detectedCMP = "CookieYes";
else if (match("OptanonConsent")) window.__detectedCMP = "OneTrust";
else if (match("CookieScriptConsent")) window.__detectedCMP = "CookieScript";
else if (match("cookiefirst-consent")) window.__detectedCMP = "CookieFirst";
else window.__detectedCMP = "Aucun";
return consent;
}
function syncConsentFromCookies() {
const consent = parseConsentByCMP();
if (!consent) return;
const same = JSON.stringify(consent) === JSON.stringify(lastSyncedConsent);
if (same) {
console.log("⏩ Consent inchangé, aucune action nécessaire.");
return;
}
lastSyncedConsent = consent;
console.log("📡 CMP détecté :", window.__detectedCMP);
console.log("📦 Consent extrait via scan cookie :", consent);
syncConsentToShopify(consent);
publishConsentEvent(consent);
}
// ▶️ Chargement de base
window.addEventListener("load", syncConsentFromCookies);
// ▶️ Événements spécifiques aux CMP
window.addEventListener("CookiebotOnAccept", syncConsentFromCookies); // Cookiebot
document.addEventListener("cookieyes_consent_update", syncConsentFromCookies); // CookieYes
window.addEventListener("OneTrustGroupsUpdated", syncConsentFromCookies); // OneTrust
window.addEventListener("cf_consent", syncConsentFromCookies); // CookieFirst
window.addEventListener("CookieScriptCategory-strict", syncConsentFromCookies); // CookieScript
</script>
This code transfers your CMP choices to the Shopify.customerPrivacy API, so that Shopify, and therefore the customer event that manages GTM and Consent Mode, knows how to adapt it.
🎯 To adapt the consent synchronization script to another CMP, just follow three simple steps: first, plug in the right triggering event (each CMP has its own: CookiebotOnAccept, cookieyes_consent_updateetc.); then, read consent choices either via an exposed JS API (such as window.Cookiebot.consent), or by scanning cookies with a regex (the most robust solution); finally, map CMP categories to the format expected by Shopify (analytics, marketing, preferences, sale_of_data). Please note: Axeptio does not work with standard events: it is asynchronous, requires _axcb.push() and manual access to choices. In brief: avoid Axeptio if possible It's heavier to integrate than the others.
Step 3: Create a Custom Pixel that pushes consent to Google/Microsoft
- Go to Settings > Customer Events)
- Click on Add custom pixel
- Paste this code:
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
let customerPrivacyStatus = init.customerPrivacy;
let lastConsentHash = null;
const initializeGtmTag = (w, d, s, l, i) => {
w[l] = w[l] || [];
w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
const f = d.getElementsByTagName(s)[0];
const j = d.createElement(s);
const dl = l !== 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
};
// 🔁 Charge GTM
initializeGtmTag(window, document, 'script', 'dataLayer', 'GTM-XXXXXXX');
const getConsentObject = (privacy) => ({
ad_storage: privacy?.marketingAllowed ? 'granted' : 'denied',
analytics_storage: privacy?.analyticsProcessingAllowed ? 'granted' : 'denied',
ad_user_data: privacy?.saleOfDataAllowed ? 'granted' : 'denied',
ad_personalization: privacy?.preferencesProcessingAllowed ? 'granted' : 'denied',
});
const getUetConsentObject = (privacy) => ({
ad_storage: privacy?.marketingAllowed ? 'granted' : 'denied',
});
const logConsentStatus = (title, consentObj) => {
console.log(`%c${title}`, 'background: black; color: white; font-weight: bold; padding: 2px;');
Object.entries(consentObj).forEach(([key, value]) => {
const color = value === 'granted' ? 'green' : 'red';
console.log(`%c${key}: %c${value}`, 'font-weight:bold;', `color: ${color}`);
});
};
// ❌ Valeurs par défaut (obligatoire)
gtag('consent', 'default', {
ad_storage: 'denied',
analytics_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
wait_for_update: 500
});
window.uetq = window.uetq || [];
window.uetq.push('consent', 'default', { ad_storage: 'denied' });
// ✅ Consentement : update ssi changé
function syncConsentToPixels(privacy) {
const gtagConsent = getConsentObject(privacy);
const uetConsent = getUetConsentObject(privacy);
const currentHash = JSON.stringify(gtagConsent) + JSON.stringify(uetConsent);
if (currentHash === lastConsentHash) {
console.log("⏩ Consent mode Google/Microsoft inchangé, aucun push.");
return;
}
lastConsentHash = currentHash;
gtag('consent', 'update', gtagConsent);
window.uetq.push('consent', 'update', uetConsent);
logConsentStatus('🔍 Consent mode Google/Microsoft mis à jour :', gtagConsent);
dataLayer.push({ event: "consent_mode_updated" });
}
// 🔄 Consent initial
syncConsentToPixels(customerPrivacyStatus);
// 🔁 Écoute des changements
api.customerPrivacy.subscribe('visitorConsentCollected', (event) => {
customerPrivacyStatus = event.customerPrivacy;
syncConsentToPixels(customerPrivacyStatus);
});
// Étape : pousser les Customer Events (exemple)
// analytics.subscribe("page_viewed", (event) => {
// console.log("Page vue :", event);
// });
This pixel reads the actual state of Shopify consent (via the Customer Privacy API) and sends it to gtag() to inform Google (Analytics, Ads...) & Microsoft.
Connecting the Pixel
After pasting the code, click on "Save" button then "Connect to activate the pixel.
⚠️ Warning: no integration of your CMP in GTM
On Shopify, the CMP script cannot be injected by GTM because GTM is contained in a sandbox (Custom Pixel). This requires separate logics:
- Shopify manages front-end and consent via your theme's integrated CMP (.liquid files)
- The Custom Pixel (customer event) transmits this consent to the dataLayer
- Custom Pixel adapts consent mode
- GTM fires or blocks tags based on consent (consent mode or not)
Recommended method: Pandectes + Elevar (without code)
If you're looking for a reliable, GDPR-compliant and code-free solution to manage consent (Google consent mode v2) and tracking on Shopify, the combination of Pandectes (CMP) and Elevar (Tag Management Suite) is preferred.
Why this combination is ideal
- ✅ The Google/Microsoft Consent Mode is automatically managed via GTM
- ✅ Synchronized user consent without coding, thanks to native integration
- ✅ Server-side and client-side tracking possible via Elevar
- ✅ Shopify Checkout compatible (limits bypassed via Elevar)
Integration stages
- Install the application Pandectes GDPR Compliance from the Shopify App Store.
- In the Pandectes dashboard, click on "Customize then go to the Behavior tab.
- Under Banner type / Consent Mode select the following mode:
Accepter / Refuser(GDPR friendly) - Save changes. This setting blocks all unnecessary cookies until the user has given their consent.
- Leave the Google Consent Mode of Pandectes disabled:
(Settings > Integrations > Google Consent Mode = OFF)
This option is managed on the GTM side using the Elevar container.
Import the Elevar container template with Pandectes into GTM
- Install the application Elevar. Then log in to your Elevar account
- Go to "Pre-Built Tags search
Pandectes
-
Download the Pandectes container
-
In GTM, click on "Admin > Import container
-
Select the downloaded file, then:
- Select "Merge
- And "Overwrite conflicting tags, triggers and variables
-
Publish the container by clicking on "Publish
What integration does automatically
- Initialize GTM with a strict
consent default - Send a
consent updateas soon as the user interacts with the banner - Match each consent type with the right GTM variables (analytics, ads...)
What about Shopify scripts outside GTM?
If you use Shopify apps such as Klaviyo or scripts injected into the theme, these are not automatically blocked by GTM. Pandectes offers a solution for this:
- Using Pandectes' "Script blocking" function
- Add URL regex to block calls to third-party tracking domains
- Or ask Pandectes support to do it for you
Conclusion: this method is turnkey for Shopify e-tailers. It requires no code customization and even works with complex configurations (checkout, server-side, etc.).
To remember: The combination of Pandectes + Elevar enables complete consent management without writing a single line of JavaScript. This is the recommended method for any Shopify store looking for a compliant, scalable solution.
🧪 Test and debug
- Chrome DevTools > Network > Search
collect?v=2 - Inspect console for logs
🟢 Consent Mode mis à jour - Check that events are not sent without consent