How to set up a cookie consent banner (CMP) on Shopify: every case and its effect on tracking

Blocking, optional or no banner, GTM or theme.liquid, the first page view before consent, the checkout, and how to debug it.

A cookie consent banner decides what your tracking is allowed to see. Set it up well, and GA4, Google Ads and Meta get every signal they’re allowed to have. Set it up badly, and you get purchases in Direct, landing pages that look like they lose everyone, Meta landing page views falling, and sometimes tags that fire before anyone agreed. This guide covers how to set up a consent management platform (CMP) properly on Shopify: the choice of banner, where to load it, what happens to the first page view before consent, how to share consent with the checkout, and how to debug it.

This is a tracking guide, not legal advice. What your banner must show, and where, is a question for your lawyer or DPO.

What a CMP has to do on Shopify

On most websites, a CMP shows a banner and tells your tags what the visitor chose. On Shopify, it has four jobs:

  1. Collect and store the choice, by category: analytics, marketing, preferences, and sale of data where it applies.
  2. Tell Google tags through Consent Mode v2: analytics_storage, ad_storage, ad_user_data and ad_personalization.
  3. Block or allow every other tag: the Meta Pixel, TikTok, Pinterest, Clarity, Hotjar, and scripts added by apps.
  4. Pass the choice to Shopify through the Customer Privacy API, so Shopify’s own pixels, app pixels, your custom pixel and the checkout all know what the visitor accepted.

Most broken setups I audit do the first two and forget the last two. The banner looks fine, Google tags respect it, and the checkout knows nothing.

Choosing your banner type

There are three ways to present consent, and each one has a direct effect on your data.

1. A blocking banner

The banner covers the page, or blocks scrolling and clicks, until the visitor chooses. Done properly, “Reject all” is as easy to find as “Accept all”.

  • For tracking: almost every visitor decides on the landing page. Your landing page hit is sent with a known consent state, so the session keeps its source: the campaign, the gclid, the UTMs. Direct and Unassigned stay low.
  • The cost: some visitors leave at the banner. They’re link clicks without landing page views in Meta, and bounces in your analytics if their page view was sent before they left.
  • Best for: stores in strict markets that want clean attribution and accept a bit of friction.

2. An optional banner

The banner sits at the bottom of the page. Visitors can browse without choosing, and many never do. In the EU, no choice means no consent.

  • For tracking: a large share of sessions stays denied the whole time. Visitors who accept on their second or third page start a tracked session there, without the landing page and often without its source. That’s one of the main causes of purchases attributed to Direct or Unassigned, and of landing page reports where your home page “loses” everyone.
  • The benefit: less friction on the first page.
  • Best for: stores that care more about the first impression than attribution. If you choose it, advanced Consent Mode and url_passthrough matter even more.

3. No banner

Some stores sell only in regions where consent isn’t required before tracking, or use an opt-out model such as the “Do not sell or share my personal information” link in some US states.

  • For tracking: everything is granted by default, so tracking is complete. In regions with opt-out rules, the Global Privacy Control signal and opt-out choices must still be honoured, and Shopify handles sale_of_data separately.
  • The risk: a store that sells in the EU, the UK or Switzerland without a banner is exposed legally, and Google requires consent signals for EEA traffic to use its ads features fully.
  • Best practice: use one CMP with rules by region: a banner for the EEA, the UK and Switzerland, granted defaults or an opt-out model elsewhere.

Where to load the CMP

MethodHow it loadsProsCons
Shopify’s own cookie bannerSettings → Customer privacyFree, built into the Customer Privacy API and the checkoutFew design and category options, no Consent Mode for tags in your theme by itself
A CMP appTheme app embedNo code, usually integrated with the Customer Privacy API, survives theme changesLoad order isn’t always under your control, quality of the Shopify integration varies
In theme.liquidCMP script at the top of <head>Loads first, before GTM and apps, predictable orderTied to the theme, you connect the Customer Privacy API yourself if the CMP doesn’t
Through GTMCMP tag on the Consent Initialization triggerNo theme edits, Consent Mode handled by the CMP’s templateCan’t block scripts outside GTM, shows later, disappears if GTM is blocked

Loading it in theme.liquid

The CMP and the Consent Mode defaults must come before GTM in the <head>:

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  gtag('consent', 'default', {
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    analytics_storage: 'denied',
    wait_for_update: 500
  });
  gtag('set', 'url_passthrough', true);
</script>
<!-- your CMP script -->
<!-- Google Tag Manager -->

If the CMP reads the visitor’s saved choice and sends a consent update before GTM fires its first tags, returning visitors are tracked from their first hit. If the defaults come after GTM, the first tags fire without any consent state: either they’re blocked by mistake, or they send data they shouldn’t.

Loading it through GTM

Most CMPs (Cookiebot, Didomi, Axeptio, OneTrust, Usercentrics and others) have a GTM template. Put it on the Consent Initialization – All Pages trigger so it sets defaults and restores saved choices before any other tag. Three limits to know:

  • It only controls GTM. Scripts in your theme, app embeds and Shopify’s own pixels don’t go through GTM. Your CMP must still tell Shopify about the choice, and app pixels must be controlled through the Customer Privacy API.
  • The banner appears later, after GTM loads, so more visitors scroll or leave before they see it.
  • If GTM is blocked, by an ad blocker for example, there’s no banner. Your GTM tags don’t run either, but anything outside GTM does.

If you use a CMP app on Shopify, check whether it already sets Consent Mode. Don’t also add its GTM template: two sources of consent updates produce conflicting states.

Consent Mode for GA4 and Google Ads

Consent Mode has two modes, and the difference is what happens before the visitor chooses:

  • Basic: Google tags don’t load until consent is granted. Nothing is sent before, not even the consent state. Visitors who refuse are invisible, and there’s nothing to model.
  • Advanced: Google tags load with consent denied and send cookieless pings: no cookies, no persistent ID, marked as denied. GA4 and Google Ads use them for modeling. Once the visitor accepts, the tags send full data.

For most Shopify stores, advanced mode with denied defaults in the EEA, the UK and Switzerland is the right choice. Two settings help it:

  • url_passthrough keeps ad click identifiers in your internal links when ad_storage is denied, so a conversion can still be attributed to the click after a later accept.
  • ads_data_redaction removes ad click identifiers from pings when ad_storage is denied, for stores that want to be stricter.

Use region-specific defaults if you sell outside Europe: denied for EEA countries, the UK and Switzerland, granted elsewhere if that’s legal for you. Consent Mode uses the most specific region that matches.

GA4’s behavioral modeling needs enough volume: Google’s guidance is at least 1,000 events a day with analytics consent denied for 7 days, and at least 1,000 daily users with consent granted on 7 of the last 28 days. Smaller stores won’t be modeled, but advanced mode still gives Google Ads more signals than basic.

Tags that aren’t Google

Meta, TikTok, Pinterest, Clarity and most other tags don’t understand Consent Mode the way Google tags do. They must be blocked until the right consent, then fired.

  • In GTM, set each tag’s consent settings to require ad_storage (or analytics_storage for analytics tools).
  • Add a trigger on the consent update for page-level tags such as the Meta Pixel’s PageView. GTM doesn’t fire a blocked tag again when consent changes. Without that trigger, a visitor who accepts on the landing page sends no PageView for that page, which is a common cause of a Meta landing page view rate drop.
  • Some tags have their own consent API, such as fbq('consent', 'revoke') and fbq('consent', 'grant') for Meta. If you use them, the pixel can load early and hold events until consent.
  • App pixels on Shopify, such as the Facebook & Instagram app or TikTok’s app, follow the Customer Privacy API. If your CMP doesn’t write to it, they follow Shopify’s default for the visitor’s region, which may not match the banner.

What happens to the first page view before consent?

This is where most of the damage happens. A visitor lands from a campaign, the page loads, the banner appears. What does each tool see?

ScenarioGA4Google AdsMeta (blocked until consent)
Accepts on the landing page, basic modeNothing until accept. The page view is sent only if a tag fires on the consent update.Same: no click data until accept.PageView only if a tag fires on the consent update.
Accepts on the landing page, advanced modeCookieless ping, then full data after accept. Tests by practitioners show the Google tag can resend the page’s hits after consent is granted, but Google doesn’t document it: test it.Cookieless ping, then the click is stored once ad_storage is granted.PageView only if a tag fires on the consent update.
Accepts on a later pageThe tracked session starts on that page. The landing page and often its source are lost: Direct, Unassigned or a self-referral.The click can still be attributed if url_passthrough kept the gclid in the URL.Landing page view lost for that click.
Never choosesAdvanced: cookieless pings only. Basic: nothing.Advanced: pings for modeling. Basic: nothing.Nothing.
RefusesSame as never chooses.Same as never chooses.Nothing.

Does GA4 resend the page view in the background once consent is granted? Not in a way you should rely on. In practice:

  1. Returning visitors: the CMP must restore their saved choice before GTM’s first tags. Then their landing page hit is complete. Check it with GTM Preview: the consent state on the first event must already be granted.
  2. New visitors who accept on the landing page: make sure the page view, and the Meta and TikTok page events, fire on the consent update when they haven’t fired with consent yet. Test that it isn’t sent twice.
  3. New visitors who accept later: keep campaign information on internal links with url_passthrough, and accept that some attribution is lost. A blocking banner reduces this case.

Sharing consent with the checkout

Your theme’s banner doesn’t run in the checkout, and neither does GTM from your theme. The checkout only knows what the visitor chose if your CMP wrote it to Shopify.

  1. The CMP calls the Customer Privacy API with setTrackingConsent whenever the visitor chooses, for analytics, marketing and preferences, and sale_of_data where it applies. Many CMP apps do this for you. Check it, don’t assume it. The code is in Consent Mode v2 on Shopify with the Customer Privacy API.
  2. Your custom pixel reads it from init.customerPrivacy when it loads, and listens for changes with customerPrivacy.subscribe("visitorConsentCollected"). It sets Consent Mode defaults and updates from those values before GTM loads.
  3. Choose the pixel’s customer privacy setting consciously. If it requires consent, Shopify only loads the pixel once the visitor accepts, so there are no cookieless pings in the checkout. If it doesn’t, the pixel always loads, and your code must apply Consent Mode itself.

Visitors who reach the checkout without visiting your store pages, from an abandoned cart email or a Shop Pay link for example, never saw your banner. They get Shopify’s default for their region. Decide whether that’s what you want.

Don’t read or write Shopify’s consent cookies directly. Shopify says their format can change. Use the API.

How to debug consent

In the browser console

// what Shopify knows
Shopify.customerPrivacy.currentVisitorConsent();

// what Google tags know (latest consent commands)
dataLayer.filter((e) => e[0] === "consent");

In GTM Preview

Click the first event, Consent Initialization, then the Consent tab. You should see the defaults set there, before any tag fires. After accepting, the consent update event should show the new state. On each tag, the consent column shows whether it was blocked, and why.

In network requests

Filter the Network tab on collect for GA4. The gcs parameter shows ad_storage and analytics_storage:

  • G100: both denied
  • G110: ads granted, analytics denied
  • G101: ads denied, analytics granted
  • G111: both granted

The gcd parameter is sent on every request and encodes all four signals, including whether each one came from a default or an update.

In the checkout

Use the Shopify Pixel Helper, and log init.customerPrivacy from your custom pixel during testing. On the purchase, check gcs: it should match what the visitor chose on your store pages.

The test matrix

Run each case in a new private window, from a campaign URL with UTMs and a test gclid:

  1. No choice, then browse two pages.
  2. Reject on the landing page.
  3. Accept on the landing page.
  4. Accept on the second page.
  5. Accept, then change your mind in the banner settings.
  6. Accept, then complete a test order.
  7. From another region with a VPN, if you use region-specific rules.

For each case, check GA4 DebugView, the Meta Pixel Helper and the purchase. The quick version of this test is in does your cookie banner actually reach your pixels?

Symptoms of a broken CMP

SymptomLikely cause
Purchases attributed to Direct or UnassignedConsent not passed to the checkout, or sessions starting after a late accept without the landing page. See Shopify purchases attributed to Direct or Unassigned.
High bounce rate, many one-page sessionsThe page view fires again on consent update with a new client ID, splitting one visit into two sessions, or the landing page hit is missing so sessions look like they start and end on one page.
Landing pages that look like the second page of a visitTracked sessions start after a late accept on a non-blocking banner.
Meta landing page view rate dropsThe pixel is blocked on page load and never fired after consent, or a new banner lowers acceptance.
Google Ads conversions drop after a banner changeBasic mode or missing ad_user_data, so conversions and enhanced conversions are lost for consented users too. Check Consent Mode status in Google Ads diagnostics.
GA4 traffic falls in some countries onlyWrong region-specific defaults.
Purchases consented on the store, denied in the checkoutThe CMP doesn’t call setTrackingConsent.
Tags fire before any choiceThe CMP or the defaults load after GTM, or app scripts aren’t blocked. This is a legal problem, not only a data one.
Numbers that didn’t change at all after adding the bannerTags ignore consent. Also a legal problem.

The setup I recommend for most Shopify stores

  1. A CMP with a real Shopify integration that writes to the Customer Privacy API, or Shopify’s own banner if your needs are simple.
  2. Loaded before GTM, through its app embed or at the top of theme.liquid, with Consent Mode defaults set before any tag.
  3. Advanced Consent Mode with denied defaults in the EEA, the UK and Switzerland, url_passthrough on, and region rules elsewhere.
  4. Non-Google tags blocked until consent, with a consent update trigger for their page events.
  5. A custom pixel that reads init.customerPrivacy and applies Consent Mode in the checkout.
  6. A blocking or prominent banner if attribution matters more to you than first-page friction, with “Reject all” as easy as “Accept all”.
  7. The test matrix after every change to the banner, the theme or GTM.

Frequently asked questions

Should I use Shopify’s cookie banner or a third-party CMP?

Shopify’s banner is enough for simple setups and is always connected to the checkout. A third-party CMP gives you more control over categories, design, regions and Consent Mode, but check that it writes to the Customer Privacy API.

Is it better to load the CMP in GTM or in theme.liquid?

Before GTM, through an app embed or theme.liquid, is safer: it loads first and can control scripts outside GTM. GTM works if everything you track goes through GTM.

Does GA4 send the page view again after consent is granted?

Google doesn’t document it. Practitioner tests show some hits are resent or reprocessed in advanced mode, depending on the setup. Make sure your page view fires with consent on the landing page, and test it.

Does a blocking cookie banner hurt conversions?

It can increase bounces on the first page. It also keeps attribution clean, because visitors decide on the landing page. Test both on your own store.

Why does the checkout ignore my visitor’s consent?

Your CMP isn’t writing it to Shopify’s Customer Privacy API. The checkout can’t read your banner’s own cookies.

Do I need a banner if I only sell in the US?

Not a consent banner before tracking in most states, but some states require an opt-out of selling or sharing data, and Global Privacy Control signals must be honoured. Check with your lawyer.

Want it checked?

Consent is the part of tracking that breaks most quietly. A Shopify tracking audit (from 800€) runs the full test matrix on your store and checks the banner, Consent Mode, the pixels and the checkout. My Starter package (1,300€) sets up GA4 with GTM and Consent Mode v2. Book a free 30-minute call to talk about your setup.

Elliot Latil

Full Stack Web Analytics expert: GA4, GTM, server-side tracking and Shopify. About me