Integrate with your website - Shopify
This guide will walk you through integrating Cookifi with your Shopify store.
For the purpose of this guide, we will assume
- you are using Custom Pixel and Google Tag Manager (GTM) to manage your tracking setup, and
- the Custom Pixel only pushes data to the data layer, and does not directly send data to third-party vendors, and
- consent enforcement is handled by GTM (we’ll cover how to configure that later)
- you are starting from scratch with a new Custom Pixel (if you already have one, you’ll need to adapt the existing code - if unsure how, you can always reach out for help in our Slack community).
Platform context
Section titled “Platform context”Shopify has deprecated checkout scripts and other legacy tracking methods.
Despite the limitations, the recommended and future-proof way to track customer interactions is through Customer Events, using Custom Pixels.
We’ll be making changes in a few places inside Shopify.
Storefront
Section titled “Storefront”Cookifi integration script
Section titled “Cookifi integration script”In your Cookifi admin panel, go to General > Integration script and copy the provided script:
Theme.liquid file
Section titled “Theme.liquid file”In Shopify, go to Online Store > Themes > Edit code, and search for the theme.liquid file.
Paste your Cookifi integration script at the very top of the <head>
element:
Shopify will prompt you to add defer
- go ahead and add that to the <script>
tag:
Now search for content_for_header
and paste the following code right below it:
{% render 'cookifi' %}
Save the file.
Cookifi snippet
Section titled “Cookifi snippet”Within the code editor, locate the snippets section and click Add a new snippet:
Snippet name: cookifi
Snippet content:
<script>function feedback() {const p = window.Shopify.customerPrivacy;console.log(`Tracking ${p.userCanBeTracked() ? "en" : "dis"}abled`);}
window.Shopify.loadFeatures([{name: "consent-tracking-api",version: "0.1",},],function (error) {if (error) throw error;});
// function to apply Cookifi consent values to Shopify Customer Privacy APIfunction setConsent() {
const cookifiConsent = window.cookifi;console.log("<<< Cookifi: Setting consent based on Cookifi values: ", cookifiConsent);
window.Shopify.customerPrivacy.setTrackingConsent({"analytics": cookifiConsent.analytics,"marketing": cookifiConsent.marketing,"preferences": cookifiConsent.preferences,"sale_of_data": cookifiConsent.marketing,},() => console.log("<<< Cookifi: Consent sent to pixel via CustomerPrivacyAPI."));}
// Listen to Cookifi consent load eventwindow.addEventListener("cookifiOnConsentLoad", function () {console.log("<<< Cookifi: onConsentLoad event fired!");console.log("<<< Cookifi: Current consent: ", window.cookifi);
// Wait for Shopify customerPrivacy to be available before applying consentconst existConsentShopify = setInterval(function () {if (window.Shopify.customerPrivacy) {clearInterval(existConsentShopify);setConsent();}}, 100);});</script>
Save the snippet.
Custom Pixel
Section titled “Custom Pixel”In Shopify, navigate to Settings > Customer Events and create a new Custom Pixel:
Name the pixel, e.g. GTM, and click Add pixel.
Pixel privacy settings
Section titled “Pixel privacy settings”Under Customer privacy, choose:
Permission: Not required
Data sale: Data collected does not qualify as data sale
Pixel content
Section titled “Pixel content”First, remove the default placeholder code by Shopify.
Then, paste the following code:
// initiate dataLayer & gtagwindow.dataLayer = window.dataLayer || [];window.dataLayerTemp = [];function gtag() {dataLayer.push(arguments);}
// push events to the correct dataLayer, based on whether consent has been established (i.e., loaded from the API)function safePush(eventData) {if (isConsentLoaded) {window.dataLayer.push(eventData);} else {window.dataLayerTemp.push(eventData);}}
let isConsentLoaded = false;
// #1 TO DO: Google Consent Mode - Default command
// #2 TO DO: GTM container snippet
As you’ll notice, there’s two TO DO items for you to complete:
- Google Consent Mode - Default command
In your Cookifi admin panel, go to Regions and verify all required regions are configured correctly:
Then, go to General > Integration script and click the Google icon to generate the Default command for Google Consent Mode:
Copy the provided code:
And paste it in the Custom Pixel code, directly under the #1 TO DO comment.
Then remove these redundant lines at the top:
And also remove these closing lines at the bottom:
So it looks like this:
- GTM container snippet
In your GTM container, click your container ID in the top-right corner:
Copy the provided
head
snippet:And paste it directly under the #2 TO DO comment:
Finally, remove the
<script>
tags and comment lines from the code, so that the code becomes error-free:So it looks like this:
Finally, paste the following after the GTM container snippet to complete the consent sync logic:
// function to check if the current page is checkoutfunction isCheckoutPage() {return initContextData?.location?.href.includes("/checkouts/");}
// function to get the _tracking_consent cookie valuefunction getTrackingConsentCookie() {const cookie = document.cookie.split("; ").find(row => row.startsWith("_tracking_consent="));if (!cookie) return null; // no consent cookie exists
try {return JSON.parse(decodeURIComponent(cookie.split("=")[1]));} catch (error) {console.error(">>> PIXEL: Failed to parse _tracking_consent cookie: ", error);return null;}}
// handle consent on checkout pages (using the _tracking_consent cookie)if (isCheckoutPage()) {let consentCookie = getTrackingConsentCookie();let customerPrivacyStatus = {analyticsProcessingAllowed: false,marketingAllowed: false,preferencesProcessingAllowed: false,saleOfDataAllowed: false};
if (consentCookie && consentCookie.con?.CMP) {// If values exist, use themcustomerPrivacyStatus = {analyticsProcessingAllowed: consentCookie.con.CMP.a === "1",marketingAllowed: consentCookie.con.CMP.m === "1",preferencesProcessingAllowed: consentCookie.con.CMP.p === "1",saleOfDataAllowed: consentCookie.con.CMP.s === "1"};}
// Google Consent Mode - Update commandgtag("consent", "update", {analytics_storage: customerPrivacyStatus.analyticsProcessingAllowed ? "granted" : "denied",ad_storage: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",ad_user_data: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",ad_personalization: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",personalization_storage: customerPrivacyStatus.preferencesProcessingAllowed ? "granted" : "denied",functionality_storage: customerPrivacyStatus.preferencesProcessingAllowed ? "granted" : "denied",security_storage: "granted"});
window.dataLayer.push({event: "cookifi-consent-update",cookie_consent_marketing: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",cookie_consent_statistics: customerPrivacyStatus.analyticsProcessingAllowed ? "granted" : "denied",cookie_consent_preferences: customerPrivacyStatus.preferencesProcessingAllowed ? "granted" : "denied"});
// Push queued eventswindow.dataLayerTemp.forEach(item => window.dataLayer.push(item));window.dataLayerTemp = [];
isConsentLoaded = true;}
// handle consent on storefront (using visitorConsentCollected event)if (!isCheckoutPage()) {api.customerPrivacy.subscribe("visitorConsentCollected", (event) => {let customerPrivacyStatus = event.customerPrivacy;
// Google Consent Mode - Update commandgtag("consent", "update", {analytics_storage: customerPrivacyStatus.analyticsProcessingAllowed ? "granted" : "denied",ad_storage: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",ad_user_data: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",ad_personalization: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",personalization_storage: customerPrivacyStatus.preferencesProcessingAllowed ? "granted" : "denied",functionality_storage: customerPrivacyStatus.preferencesProcessingAllowed ? "granted" : "denied",security_storage: "granted"});
window.dataLayer.push({event: "cookifi-consent-update",cookie_consent_marketing: customerPrivacyStatus.marketingAllowed ? "granted" : "denied",cookie_consent_statistics: customerPrivacyStatus.analyticsProcessingAllowed ? "granted" : "denied",cookie_consent_preferences: customerPrivacyStatus.preferencesProcessingAllowed ? "granted" : "denied"});
// push the queued events from the temporary dataLayer to the main dataLayerwindow.dataLayerTemp.forEach(item => window.dataLayer.push(item));isConsentLoaded = true;
window.dataLayerTemp = [];});}
Subscribe to Customer Events
Section titled “Subscribe to Customer Events”Now that consent handling is in place, you can subscribe to the available standard Customer Events from Shopify.
Here’s how to do it: instead of pushing the event payload into the dataLayer directly, you’ll always use the safePush
function.
Here’s an example code you can use to push a page view event:
analytics.subscribe("page_viewed", (event) => {
const eventContextData = event.context?.document;const eventPayload = {event: "page_view",page_location: eventContextData?.location?.href,page_referrer: eventContextData?.referrer,page_title: eventContextData?.title,};
safePush(eventPayload);});
This ensures that the data is only pushed once consent has been properly established.
GTM configuration
Section titled “GTM configuration”To actually send events to GA4 (or other tools) based on consent, you’ll need to configure GTM accordingly.
Please refer to this this guide for more information.
To hook to the consent update event in GTM, you can use the following event name for your Custom Event trigger:
cookifi-consent-update
Useful resources
Section titled “Useful resources”If you need an end-to-end real-world example with ready-to-use code examples & GTM container templates compatible with Cookifi, check out this article.