All posts
·16 min read

Google Consent Mode v2 for Shopify (2026): the complete setup guide

Google Consent Mode v2 is mandatory for EU/EEA traffic in Google Ads. This guide covers every signal, the June 2026 ad_storage change, how to wire GCM v2 on Shopify with and without code, GTM setup, and how to verify it's actually working.

google-consent-modegdprgoogle-adsshopifyga4

Quick Answer

TL;DR: Google Consent Mode v2 is mandatory for any Shopify store running Google Ads or GA4 for EU/EEA traffic. Four signals matter — ad_storage, analytics_storage, ad_user_data, ad_personalization. Set them all to denied in the page <head> before any Google tag loads, then update them when the visitor consents. As of June 15, 2026, ad_storage is now the sole gate on GA4→Google Ads data — misconfigure it and remarketing quietly dies. Consentico wires all of this up automatically when you enable the app embed.

If you run paid traffic to your Shopify store from Google Ads or rely on Google Analytics 4 for attribution, Google Consent Mode v2 is not optional for EU/EEA visitors. As of March 2024, Google requires advertisers to send consent signals through GCM v2 — without them, your remarketing lists degrade, Smart Bidding loses training data, and Google's own compliance stance on your account shifts.

This guide walks through what GCM v2 actually is, every signal you need to set, the critical June 2026 ad_storage change, how to wire it up on Shopify (with and without code), how to test that it's working, and the mistakes we see merchants make most often.

Updated July 30, 2026 to cover the June 15 2026 ad_storage gating change and Google's July 2025 enforcement escalation that started degrading Smart Bidding for stores without GCM v2 within days of activation.

Google Consent Mode is a mechanism for telling Google's tags (GA4, Google Ads, Floodlight, YouTube conversion tags) whether the visitor has consented to tracking. The tag still loads — but its behaviour changes based on the consent signals you send.

  • Consent granted: Tags fire normally — full pageviews, conversions, and audience signals.
  • Consent denied: Tags fire in a degraded, cookieless mode that sends anonymous pings so Google's machine-learning models can estimate ("model") the conversions and audiences you would have seen.

Version 2 upgraded v1 by adding two new required parameters, driven by the EU Digital Markets Act requirement that ad-purpose consent be granular:

ParameterPurposeRequired in v2?
ad_storageCookies/IDs used for advertisingYes (v1 + v2)
analytics_storageAnalytics cookiesYes (v1 + v2)
ad_user_dataWhether user data can be sent to Google for advertisingYes (new in v2)
ad_personalizationWhether Google can use that data for personalised ads / remarketingYes (new in v2)
functionality_storagePreferences (language, region)Optional
personalization_storageNon-ad personalisationOptional
security_storageAnti-fraud, reCAPTCHASet to granted — no consent needed

Why this matters for Shopify merchants

Three things change materially when you implement GCM v2 correctly:

1. Compliance

GCM v2 is the mechanism Google trusts to know whether you've collected valid consent. Without it, EU traffic is non-compliant from Google's perspective regardless of what your banner says or does. This is a Google policy layer sitting on top of GDPR itself — the underlying legal requirements are in our Shopify GDPR compliance guide.

2. Revenue — modeled conversions

Modeled conversions only work if Google receives the cookieless pings that GCM v2's denied-state generates. A banner that outright blocks GA4 (with no Consent Mode wiring at all) costs you that modeled-conversion fallback. Stores that switch from "block everything" to properly-configured GCM v2 typically see 15–30% of "lost" conversions return as modeled — real revenue that was previously invisible.

3. Audiences — remarketing lists

If you're not sending GCM v2 signals, your Google Ads audiences degrade. Existing remarketing lists shrink as cookies expire and aren't replaced. As of Google's July 2025 enforcement escalation, we've seen stores lose 40–60% of their remarketing list size within 30 days of removing GCM v2 signals.

The June 15, 2026 ad_storage change (critical)

Until June 2026, some CMPs used a workaround: set ad_storage: denied but leave Google Signals toggled on in GA4 admin. That was enough to keep some data flowing to Google Ads for remarketing purposes.

As of June 15, 2026, that's over. Google now treats ad_storage as the sole gate on whether GA4 data flows to Google Ads. The GA4 admin Google Signals toggle no longer overrides it.

Practical implications:

  • If ad_storage: denied, no data reaches Google Ads for that visitor. Full stop.
  • If your CMP is setting ad_storage: denied even after the visitor accepts marketing consent, your remarketing pool is being silently starved.
  • ad_personalization will similarly become the governing parameter for whether Analytics data feeds personalized ads (rollout in progress).

Action: Verify your CMP sets ad_storage: granted when the user accepts marketing cookies (not just analytics). Consentico maps Shopify's marketing category to ad_storage + ad_user_data + ad_personalization automatically.

The "default deny" pattern

The compliant pattern Google describes — and the one Consentico implements out of the box — is:

  1. Before any tag loads, set GCM v2 defaults to denied for every signal except security_storage.
  2. Wait for the visitor to interact with your consent banner.
  3. Update the GCM signals based on their decision: granted for everything they accepted, denied for what they didn't.

The critical word is before. If GA4 fires before you set defaults, the first pageview is sent with the implicit-grant assumption — exactly the leak GDPR Article 5(3) was written to stop.

This is why script blocking matters even with GCM v2. Even when you set ad_storage: denied, Google's tags still load. The signal stops them setting cookies, but a misconfigured tag manager could still leak data through unrelated mechanisms. A proper consent banner blocks the script load entirely until consent, and sets GCM v2 signals as a belt-and-suspenders measure. See how to add a no-code Shopify cookie banner for the install flow.

How Consentico wires it up

Consentico's storefront banner does three things in this exact order, before anything else loads (full walkthrough in GCM v2 setup docs):

// 1. Set GCM v2 defaults — denied for everything trackable.
gtag('consent', 'default', {
  ad_storage: 'denied',
  analytics_storage: 'denied',
  ad_user_data: 'denied',
  ad_personalization: 'denied',
  functionality_storage: 'denied',
  personalization_storage: 'denied',
  security_storage: 'granted',
  wait_for_update: 500,
});

// 2. Block tracking scripts until consent
//    (createElement override + MutationObserver + type="text/plain" fallback).

// 3. Render the banner. On user choice:
gtag('consent', 'update', {
  ad_storage: userConsent.marketing ? 'granted' : 'denied',
  analytics_storage: userConsent.analytics ? 'granted' : 'denied',
  ad_user_data: userConsent.marketing ? 'granted' : 'denied',
  ad_personalization: userConsent.marketing ? 'granted' : 'denied',
});

The wait_for_update: 500 tells Google to delay sending pings for 500ms while the banner decides. That's enough time for the visitor to either click Accept (in which case GA4 fires normally) or to time out and fall through to the cookieless modeled-conversion path.

Step-by-step setup on Shopify

If you're using Consentico, this is already wired up — install the app, enable the theme app extension, and you're done. If you're rolling your own or using a script-snippet CMP, here's the sequence.

DIY setup (no CMP)

If you're wiring GCM v2 by hand — headless Hydrogen, custom theme, or you specifically don't want a CMP — the exact sequence is:

1. Add the gtag stub before any script tags

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
</script>

2. Set defaults to denied

In the same inline script, before any GTM or GA4 snippet:

<script>
  gtag('consent', 'default', {
    ad_storage: 'denied',
    analytics_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    functionality_storage: 'denied',
    personalization_storage: 'denied',
    security_storage: 'granted',
    wait_for_update: 500,
  });
</script>

The simplest approach is to override document.createElement to intercept <script> tag creation, inspect the src, and skip insertion if the URL matches your blocklist (Google Tag Manager, Meta Pixel, Klaviyo, TikTok Pixel, etc.).

4. Render the banner

When the visitor decides, call:

gtag('consent', 'update', {
  ad_storage: acceptedMarketing ? 'granted' : 'denied',
  analytics_storage: acceptedAnalytics ? 'granted' : 'denied',
  ad_user_data: acceptedMarketing ? 'granted' : 'denied',
  ad_personalization: acceptedMarketing ? 'granted' : 'denied',
});

Then unblock the previously-blocked scripts.

5. Persist the choice

Use localStorage (essential category, doesn't require consent itself) so the visitor doesn't see the banner on every page load. Rotate the storage key on version bumps if you materially change categories.

Setting up GCM v2 in Google Tag Manager

GTM is where most "GCM v2 is broken" bugs actually live. The order matters:

  1. Do NOT put the consent defaults in a GTM tag. GTM loads after your page — by the time the GTM container fires the defaults, GA4 has already sent the first pageview.
  2. Put defaults inline in <head> before the GTM snippet. GTM will inherit whatever dataLayer state exists.
  3. Set your consent-mode-aware tags (GA4, Ads Conversion, Floodlight) to Additional Consent Checks: Not Set — GCM v2 handles the gating itself, and adding an extra check causes double-firing bugs.
  4. Use GTM's built-in Consent Overview (Admin → Container → Consent Overview) to audit which tags respect which signals. Any tag showing "No consent required" that fires a Google request is a leak.

Common mistakes we see

Setting defaults inside GTM

GTM loads after your page. By the time the GTM container fires the consent defaults, GA4 has already sent the first pageview. Set defaults inline in the page <head> before anything else.

Treating ad_user_data and ad_personalization as the same

They're not. ad_user_data is whether you can send data to Google for ads use; ad_personalization is whether Google can use that data for personalized ads. A visitor might consent to one but not the other under the EU DMA framework.

Forgetting security_storage: granted

Setting security_storage: denied breaks reCAPTCHA and other Google security widgets. There's no compliance reason to deny it — it covers anti-fraud, not tracking.

Rebuilding the banner on every navigation

SPAs (Hydrogen, headless setups) sometimes re-mount the banner on route change, which can re-trigger the default-deny ping. Set GCM defaults once at app boot, not per-page.

Mapping the wrong category to ad_storage

Post-June 2026, ad_storage gates all data flow to Google Ads. If your CMP maps analytics-only consent to ad_storage: granted, you're leaking data. If it maps marketing consent to ad_storage: denied, you're breaking remarketing. Verify the mapping.

How to verify GCM v2 is actually working

Three checks, easiest to hardest:

1. Google Tag Assistant (30 seconds)

  • Install Tag Assistant Legacy for Chrome
  • Visit your storefront in incognito → click the extension → Enable → refresh
  • Check the Consent tab: all four signals should show denied before you click Accept, then flip to granted

2. Network tab (2 minutes)

  • Open your storefront in incognito → open DevTools → Network tab
  • Filter for collect
  • Refresh. First hit to region1.google-analytics.com should include gcs=G100 and dma=1
  • Click Accept. Next collect hit should show gcs=G111

The gcs values decode as G + 3 bits: 100 = defaults denied, 111 = all granted, 110 = analytics-only, etc.

  • GA4 → Reports → Realtime → filter by your test session
  • You should see the session appearing in Realtime before Accept (proving cookieless pings work)
  • After Accept, session should upgrade to a full authenticated session with user_id if configured
  • In Tag Assistant, the Consent Coverage report should show 100% of Google tags respecting consent

If any of these fail, GCM v2 isn't correctly set up — regardless of what your CMP admin panel says.

Migrating from GCM v1 to v2

If you're on v1 (only four signals), here's the minimum diff:

gtag('consent', 'default', {
  ad_storage: 'denied',
  analytics_storage: 'denied',
+ ad_user_data: 'denied',
+ ad_personalization: 'denied',
  functionality_storage: 'denied',
  personalization_storage: 'denied',
  security_storage: 'granted',
  wait_for_update: 500,
});

...and the same two additions in your update call. That's it structurally, but:

  • Verify your CMP UI actually surfaces per-purpose consent to the visitor for ad_user_data vs ad_personalization. Consentmo, CookieYes, and CookieFirst all did this correctly by 2024; some smaller CMPs still bundle them.
  • Test with Tag Assistant that all four signals move together after Accept.

Frequently asked questions

Summary

Google Consent Mode v2 is a non-negotiable requirement for any Shopify merchant running paid traffic in the EU/EEA. The pattern is:

  1. Default-deny everything trackable, before any tag loads.
  2. Block third-party scripts until consent (belt-and-suspenders).
  3. Update GCM signals when the visitor decides — mapping their category choices onto the four v2 signals correctly.
  4. Verify with Tag Assistant + DevTools Network before you assume it works.

If you're using Consentico, this is wired up the moment you enable the app embed — including the June 2026 ad_storage mapping. If you're DIY-ing it, the order of operations is what matters most: defaults go in before GTM, and script blocking runs in addition to GCM signals, not instead of them.

For a comparison of how the major Shopify cookie apps stack up on GCM v2 specifically, see best cookie consent apps for Shopify. For direct head-to-heads: Consentico vs Cookiebot, vs CookieYes, vs Cookiefirst, vs Consentmo.

Want a free GCM v2 audit of your store? Install Consentico and run a scan — it'll flag any unblocked tracking scripts and tell you whether your current banner is sending the right signals.

Related reading