You already have a CMP running and a dataLayer event firing when a user makes a consent choice. The missing piece is wiring Google Consent Mode v2 correctly inside Google Tag Manager so that your ad and analytics tags respond to those signals in real time. This guide walks through every GTM config you need — from the opening gtag default call to the url_passthrough flag — and ends with a Tag Assistant debug checklist so you can verify everything before going live.
How Consent Mode v2 Works in GTM (30-Second Mental Model)
Consent Mode sits between your CMP and your Google tags. It communicates via two calls:
- Default call — fires immediately when the page loads, before any banner interaction, to set conservative fallback states.
- Update call — fires after the user accepts or declines, replacing the defaults with the actual consent values.
GTM handles both calls through a dedicated Consent Initialization trigger (for the default) and a Custom Event trigger tied to your CMP’s dataLayer event (for the update).
Step 1 — Enable Consent Overview in GTM
Before creating any tags, turn on the built-in Consent Overview panel:
- In your GTM container, click the shield icon (Consent Overview) in the left rail.
- If prompted, enable the feature for the container.
This panel will later show you which tags have consent checks attached and which are still unguarded — critical for your audit step.
Step 2 — Create the Default Consent State Tag
This tag runs once, on every page, before any other tag. It tells Google to treat all signals as denied until the user says otherwise.
- Create a new tag. Tag type: Google Tag (or a Custom HTML tag if you prefer explicit code).
- If using Custom HTML, paste the following:
<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',
'functionality_storage': 'denied',
'personalization_storage': 'denied',
'security_storage': 'granted',
'wait_for_update': 500
});
</script>
Trigger: Consent Initialization - All Pages. This is a special GTM trigger that fires before all other triggers, guaranteeing the defaults land before any Google tag can execute.
The wait_for_update value (in milliseconds) tells Google tags to pause briefly for an update signal before making modelled assumptions. 500 ms is a safe default; lower it to 300 ms on fast CMPs.
Step 3 — Create the Consent Update Tag
When your CMP fires its dataLayer event (for example, cmp_consent_update), this tag reads the user’s choices and passes them to Consent Mode.
- Create another Custom HTML tag.
- Use
dataLayervariables to capture the per-category consent values your CMP writes. The exact variable names depend on your CMP; adjust accordingly.
<script>
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'update', {
'ad_storage': '{{DLV - consent_ad_storage}}',
'ad_user_data': '{{DLV - consent_ad_user_data}}',
'ad_personalization': '{{DLV - consent_ad_personalization}}',
'analytics_storage': '{{DLV - consent_analytics_storage}}',
'functionality_storage': '{{DLV - consent_functionality_storage}}',
'personalization_storage': '{{DLV - consent_personalization_storage}}'
});
</script>
Trigger: A Custom Event trigger matching your CMP’s event name (e.g., cmp_consent_update).
Each {{DLV - ...}} placeholder is a GTM Data Layer Variable that reads the string 'granted' or 'denied' from the object your CMP pushes. Create one variable per consent category.
Step 4 — Add ads_data_redaction and url_passthrough
These two flags belong inside your default tag (or a separate config tag fired on the same Consent Initialization trigger) and control behavior when ad consent is denied:
gtag('set', 'ads_data_redaction', true);
gtag('set', 'url_passthrough', true);
ads_data_redaction— whenad_storageis denied, this strips click IDs and ad-related cookies from network requests. Set it totruefor the most privacy-conservative posture.url_passthrough— preservesgclid,dclid, andgclsrcparameters in URLs so conversion modelling can still work across page navigations without writing cookies. Recommended for sites with multi-page checkout flows.
Step 5 — Guard Your Existing Google Tags
Open the Consent Overview panel you enabled in Step 1. Any tag showing a warning icon has no consent check. For each Google Ads, GA4, and Floodlight tag:
- Open the tag settings.
- Expand Consent Settings (under Advanced Settings).
- Set the appropriate consent type (usually
ad_storagefor Ads tags,analytics_storagefor GA4).
GTM will now automatically block or allow those tags based on the current consent state without any additional trigger logic.
Debug Checklist Using Tag Assistant
Before publishing, run through this checklist in Tag Assistant (connect via tagassistant.google.com):
- Default fires first: In the event stream, the Consent Initialization event should appear before
gtm.js. Confirm the default tag fired and all six parameters showdenied. - Update fires after banner interaction: Accept consent in the banner. Look for your CMP’s custom event in the stream. The update tag should fire immediately after, with appropriate values flipping to
granted. - No tags fire pre-consent: Before interacting with the banner, check the Tags tab. Google Ads and GA4 tags should show as blocked by consent, not as fired.
ads_data_redactionactive: With ad consent denied, inspect the network request for Google Ads. Thegclidfield should be absent or redacted.url_passthroughactive: Navigate between pages while ad consent is denied. The URL should carrygclidas a query parameter rather than being dropped.- Consent Overview shows zero warnings: Return to the GTM Consent Overview panel in preview mode. Every Google tag should display a green consent check.
Common Gotchas
- If your CMP fires its event before GTM loads, the update tag will miss it. Fix: ensure the CMP event is re-pushed on
gtm.jsload, or increasewait_for_update. - Using a Google Tag tag type instead of Custom HTML? You can set consent defaults directly in the Google Tag configuration panel under Consent Settings — no Custom HTML required, but the parameters map 1:1.
- The
security_storageparameter is almost always safe to leave asgranted; it covers essential cookies like CSRF tokens.
With the default, update, and flag tags in place — and every Google tag guarded through the Consent Overview panel — your GTM container is now a properly wired Consent Mode v2 implementation. Run the Tag Assistant checklist after every CMP change or GTM deployment to catch regressions early.