Cookie Consent Integration with Shopify

If you use Shopify to manage your website, you can use the OneTrust Shopify application to add the OneTrust CMP to Storefront and Checkout.

📘

You must have both a OneTrust account and a Shopify account to utilize this integration.

Install the OneTrust Shopify app

  1. Install the OneTrust CMP from Shopify's app store.
  2. Click the Enable button under Activate OneTrust in Your Theme Editor.
  3. Click the Add Now button under Set Up Your Domain ID. You will be redirected to the Settings section of the OneTrust app. Enter your OneTrust Domain ID and click Connect.
  1. Navigate to Consent Mapping and map OneTrust category IDs to Shopify's categories. This will allow us to map OneTrust consents to Shopify's Privacy API.

Add the OneTrust CMP to Checkout

📘

A Shopify Plus plan is required to add a OneTrust Cookie Consent integration to a Shopify website Checkout.

As Shopify does not allow third-party libraries to execute JavaScript or manipulate the HTML/DOM on the Checkout pages due to privacy and security concerns, our standard mechanism to store consent (i.e. OptanonConsent or OnetrustActiveGroups) along with other CMP logic cannot be employed as usual. As such, OneTrust has developed additional functionality to allow user consent to be communicated between the Storefront and Checkout pages. To utilize this consent functionality in the Checkout page, please follow these steps:

To add OneTrust to your Checkout pages, navigate to Shopify's Settings page.

  1. Select Checkout in the sidebar menu.
  2. On the Configurations section, click Customize.
  3. Click Add app block.
  4. Select consent-management-checkout from the available blocks.
  5. Click Save.

Your OneTrust installation is complete. The CMP should now be available in both Storefront and Checkout.

Cookie Banner UI

If the end user does not interact with and dismisses the OneTrust Cookie Banner (if applicable) in the Storefront pages, a Cookie Banner UI will appear in the Checkout page. Because JavaScript cannot be evaluated here, the Cookie Banner UI will be rendered with Shopify’s UI library/components but the content is seeded from your configurations in OneTrust. Due to Shopify’s UI library, some stylings set in your template (such as button colors) may not translate over as it is not supported. If the user interacts with and dismisses the Cookie Banner UI, their consent will be persisted back to the Storefront pages.

📘

HTML elements are not interpreted by Shopify's UI library so if you have any inline HTML tags in your OneTrust template's title or description, it'll be rendered as plain text.

Consent

In order to pass consent between the Storefront and Checkout pages, OneTrust utilizes Shopify’s Customer Privacy APIs. Specifically, we use Metafields to append custom CMP data to the _tracking_consent cookie Shopify drops. The OneTrust library you added to the Checkout page will be able to read as well as write the values of the cookie. Below is an example payload OneTrust will add. The OT script in the Storefront page will retrieve the values of the cookie and sync consent onto the page.

{
   "con":{
      "CMP":{
         "a":"1",
         "m":"1",
         "p":"1",
         "s":"1"
      }
   },
   "v":"2.1",
   "region":"USFL",
   "reg":"",
   "cus":{
      "onetrust.groups":"C0001:1,C0002:1,C0004:1",
      "onetrust.datestamp":"2025-03-28T14:17:10.011Z"
   },
   "purposes":{
      "a":true,
      "p":true,
      "m":true,
      "t":true
   },
   "display_banner":false,
   "sale_of_data_region":false,
   "consent_id":"66DFC984-04a7-4899-a6c7-9ad824a8d368"
}

Actioning Consent and Cookie Blocking

There are multiple ways to block cookies on your site depending on the method you used to install them. Here are our recommendations based on each installation method:

Shopify app store

For any libraries installed through the Shopify app store, there are two methods of cookie blocking you can employ.

Shopify Privacy API

OneTrust updates Shopify’s Privacy API values based on the user's interaction with the CMP. These updates will correspond with the 'Consent Mapping' configuration in step 4 of your OneTrust installation above.

App store libraries can then access these Privacy API values and ideally take responsibility to action the consent and restrict processing if opted out. You can access these consent values with Shopify's public method: Shopify.customerPrivacy.currentVisitorConsent()

Example response:

//opted in
{marketing: 'yes', analytics: 'yes', preferences: 'yes', sale_of_data: 'yes'}

//opted out
{marketing: 'no', analytics: 'no', preferences: 'no', sale_of_data: 'no'}

//consent not yet provided
{marketing: '', analytics: '', preferences: '', sale_of_data: ''}

For example, if you are using the Google & YouTube library, Google events will fire/not fire based on consent given via the CMP without introducing any specific OneTrust blocking methods. Additionally, Shopify's own first party cookies remove themselves from the browser if consent is opted out.

OneTrust AutoBlocking

If your Shopify libraries are not actioning consent themselves as expected and further blocking needs to be done, the recommendation is to use OneTrust AutoBlocking.

📘

To utilize AutoBlocking, you have to add the AutoBlocking script to your liquid files. You can find this script in your OneTrust tenant under Scripts > Your Domain > Test/Production Script. We recommend appending it as far up in your <head> as possible as this script must be available before the main OneTrust script is loaded.

<script type="text/javascript" src="https://cdn.cookielaw.org/consent/yourDomainID/OtAutoBlock.js" ></script>

Liquid files

For any libraries added through liquid files like theme.liquid, we recommend using our Client-Side Cookie Management approaches like JavaScript Type Re-Writing or OneTrust Auto-Blocking™.

📘

If you plan to use you plan to use the OptanonWrapper function for consent handling, you will have to add the function itself into your liquid files.

<script type="text/javascript">
  function OptanonWrapper() {code here}
</script>

📘

To utilize AutoBlocking, you have to add the AutoBlocking script to your liquid files. You can find this script in your OneTrust tenant under Scripts > Your Domain > Test/Production Script. We recommend appending it as far up in your <head> as possible as this script must be available before the main OneTrust script is loaded.

<script type="text/javascript" src="https://cdn.cookielaw.org/consent/yourDomainID/OtAutoBlock.js" ></script>

Custom pixel

For any libraries added as a custom pixel (under Customer Events), we recommend retrieving consent status from the OptanonConsent cookie or the OnetrustActiveGroups data layer variable and write some custom logic to block the scripts/cookies from firing if opted out.

OneTrust blocking approaches like JavaScript Type Re-Writing or AutoBlocking can not be used as custom pixels are added as iFrames which prevent some OneTrust functions from working as expected. As such, we recommend using the two approaches above to load and block cookies before using the custom pixel approach if needed.

Headless SDK Support

This section guides you through integrating the OneTrust Consent SDK with a Shopify Hydrogen storefront, ensuring consent syncing with Shopify's Customer Privacy API.

  1. Create a new Hydrogen project

Before proceeding, make sure you have created one if you have not already. Follow the CLI to scaffold your Hydrogen storefront.

npm create @shopify/hydrogen@latest
  1. Update environment variables

Create or update your .env file with the following:

# Hydrogen/Shopify connection
SESSION_SECRET=foobar
PUBLIC_STOREFRONT_ID=75837243628
PUBLIC_STOREFRONT_API_TOKEN=3e785553116242619cf1177dabb0ab8c
PUBLIC_STOREFRONT_API_VERSION=2025-01-5
PUBLIC_STORE_DOMAIN=ot-test-first.myshopify.com
PUBLIC_CHECKOUT_DOMAIN=ot-test-first.myshopify.com
PRIVATE_STOREFRONT_API_TOKEN=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
PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID=807d0c93cbbc1d675024952401b6362e
PUBLIC_CUSTOMER_ACCOUNT_API_URL=https://shopify.customer-accounts.com

# OneTrust SDK
VITE_PUBLIC_ONETRUST_SDK_URL=https://cookie-cdn.1trust.app/scripttemplates/otSDKStub.js
VITE_PUBLIC_ONETRUST_DATA_DOMAIN=f2c79290-1100-4287-9455-26e0758ebd6b-test
VITE_PUBLIC_ONETRUST_SDK_ID=OneTrustConsentBanner

This helps you to connect your Hydrogen with your Shopify account. Make sure to prefix OneTrust-related keys with VITE_ to expose them to the client.

  1. Modify the root.tsx

Wrap your layout with the Hydrogen Analytics.Provider and render the OneTrust consent logic component:

return (
  <Analytics.Provider
    cart={data.cart}
    shop={data.shop}
    consent={data.consent}
  >
    <OneTrustConsentWithURL />
    <Outlet />
  </Analytics.Provider>
);
  1. Create the OneTrustConsentWithURL.tsx

Place this in your components or routes folder.

import {
    useAnalytics,
    useLoadScript,
} from '@shopify/hydrogen';
import { useEffect, useCallback, useRef } from 'react';

const { VITE_PUBLIC_ONETRUST_SDK_URL, VITE_PUBLIC_ONETRUST_DATA_DOMAIN, VITE_PUBLIC_ONETRUST_SDK_ID} = import.meta.env;

declare global {
    interface Window {
        OneTrust: {
            ActiveGroups?: string;
            OnConsentChanged?: (callback: () => void) => void;
        };
        OptanonActiveGroups: string;
    }
}

export function OneTrustConsentWithURL() {
    const { register, customerPrivacy } = useAnalytics();
    const { ready } = register('OneTrustConsentWithURL');
    const prevGroups = useRef('');
    const oneTrustConsentStatus = useLoadScript(
        VITE_PUBLIC_ONETRUST_SDK_URL,
        {
            in: 'head',
            attributes: {
                id: VITE_PUBLIC_ONETRUST_SDK_ID,
                type: 'text/javascript',
                'data-domain-script': VITE_PUBLIC_ONETRUST_DATA_DOMAIN,
                charset: 'UTF-8',
            },
        },
    );

  useEffect(() => {
      const inlineScript = document.createElement('script');
      inlineScript.type = 'text/javascript';
      inlineScript.innerHTML = `
        function OptanonWrapper() {
          console.log("✅ OptanonWrapper called by OneTrust.");
          // You can trigger syncing or custom logic here if needed
        }
      `;
      document.head.appendChild(inlineScript);
    }, []);
    const oneTrustSync = useCallback(() => {
        if (!customerPrivacy || !customerPrivacy?.setTrackingConsent) {
            return;
        }
        // @ts-ignore
        window.customerPrivacy = customerPrivacy;
        const activeGroups = window.OptanonActiveGroups;
        console.log('OneTrust Active Groups: ', activeGroups);
        const trackingConsent = {
            marketing: true,
            analytics: true,
            preferences: true,
            sale_of_data: true,
        };
        // Important for running project on localhost. If not passes, tracking_consnet wont drop.
        const devParameters = {
            headlessStorefront: true,
            storefrontRootDomain: 'localhost'
        };
        //new method
        customerPrivacy?.setTrackingConsent({
            ...trackingConsent,
            // @ts-ignore
            // This is for development purpose only, remove on production
            ...devParameters
          }, (ev) => {
            console.log('%c[OneTrust Sync]%c Consent data set', 'color: white; background-color: green; padding: 2px 4px; border-radius: 3px', 'color: white');         
        });
          

    }, [customerPrivacy, ready]);

    useEffect(() => {
        console.log('🔴: OneTrust consent status:', oneTrustConsentStatus);
        if (oneTrustConsentStatus !== 'done') return;

        const interval = setInterval(() => {
            const currentGroups = window.OptanonActiveGroups;
            if (currentGroups && currentGroups !== prevGroups.current) {
                prevGroups.current = currentGroups;
                oneTrustSync();
            }
        }, 500); // check every 500ms (adjust as needed)
        return () => {
            clearInterval(interval);
        };
    }, [oneTrustConsentStatus, oneTrustSync]);
    return null;
}

After completing the changes, load the page and see if the _tracking_consent cookies are dropping with the correct status in the browser dev tool > cookies.

You have now completed the configuration steps. Your Hydrogen storefront now does the following:

  • It loads OneTrust SDK on every page.
  • It listens for consent changes.
  • It maps consent categories to Shopify’s CustomerPrivacy API.

Shopify and the OneTrust Script

❗️

LEGACY

This section is deprecated. Use the approach above for Shopify integration with OneTrust.

Last Updated: Oct 26, 2021

If you use Shopify to manage your website, you can add the script to your theme header, along with the scripts for tag managers your organization uses.

Integration Steps

  1. Open your Shopify account.

  2. On the main navigation menu, select Online Store > Themes.

Shopify Themes

  1. On your current theme, hover over the Actions button. Then select Edit code. The code editor appears.

  2. Under Layout, select theme.liquid.

  3. In the <head> section of the code, paste the script.

For the integration to work, you must have a published script. For information on how to publish a script, see Getting Started with Cookie Compliance.

Theme Liquid

  1. Click the Save button.

Blocking Shopify Server-side Cookies

Below is an example of how you can use the OneTrust OptanonWrapper() callback to pass through consent values to Shopify Privacy API. For more information, see Using the OptanonWrapper Callback Function.

You can rename the performanceCookieCategory variable and change the value based on cookie category IDs. When renaming, make sure the value is updated based on the consent you want to associate with the Shopify API.

If you rename the performanceCookieCategory variable, you must rename the variable anywhere it's referenced.

<script>

const performanceCookieCategory = 'C0002,';

function waitForOneTrust() {
  hasOneTrustLoaded();
  let attempts = 0;
  const interval = setInterval(function () {
    if (hasOneTrustLoaded() || attempts > 100){
      clearInterval(interval);
    } 
    attempts++;
  }, 100)
}

function hasOneTrustLoaded() {
  if (typeof window.OnetrustActiveGroups === 'string') {
    //check now
    optanonWrapper()
    // and wrap and trigger after cookie opt-in
    window.OptanonWrapper = optanonWrapper;
    return true;
  }
  return false;
}

function sendConsent(trackingConsent) {
  window.Shopify.customerPrivacy.setTrackingConsent(trackingConsent, () => {
    console.log('Happy Days')
  });
}

function optanonWrapper() {
  const trackingConsent = !!window.OnetrustActiveGroups.includes(performanceCookieCategory);       window.Shopify.loadFeatures(
    [
      {
        name: 'consent-tracking-api',
        version: '0.1',
      },
    ],
    error => {
      if (error) {
        throw error; 
      }
      sendConsent(trackingConsent)
    },
  );   
}

(function () {
  waitForOneTrust();
})();

</script>