Google Consent Mode v2
Since March 2024, Google requires Consent Mode v2 signals (ad_user_data, ad_personalization) for EEA traffic. ConsentLoop implements the whole dance — defaults before tags load, updates after every choice — with one flag.
ConsentLoop.run({
categories: { analytics: {}, marketing: {} },
googleConsentMode: true,
});
What happens
- Immediately at
run()(or the loader, withdata-gcm):gtag('consent', 'default', …)is pushed with everything denied exceptsecurity_storage, pluswait_for_update: 500. Returning visitors get their stored state baked into the default — no denied-window flicker. - After every choice:
gtag('consent', 'update', …)with the mapped state.
⚠️Load ConsentLoop before your gtag/GTM snippet in the document so defaults win the race. With
defer on both, order in HTML is the order of execution.Default mapping
| Category | Consent Mode keys |
|---|---|
necessary | security_storage (always granted) |
functionality | functionality_storage, personalization_storage |
analytics | analytics_storage |
marketing | ad_storage, ad_user_data, ad_personalization |
Custom categories? Provide your own map (unmapped keys stay denied):
googleConsentMode: {
map: {
analytics: ["analytics_storage"],
embeds: ["ad_storage"],
personalization: ["personalization_storage", "functionality_storage"],
},
waitForUpdate: 500,
}
Live inspector
This page runs ConsentLoop with googleConsentMode: true. Current state, straight from this page’s dataLayer:
dataLayer pushes
Putting it together with gtag
<!-- 1. ConsentLoop first: pushes the consent default -->
<script defer src="https://cdn.jsdelivr.net/npm/consentloop/dist/consentloop.loader.min.js" data-gcm></script>
<!-- 2. Then Google — ungated: Consent Mode governs it cookielessly -->
<script defer src="https://www.googletagmanager.com/gtag/js?id=G-XXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag("js", new Date());
gtag("config", "G-XXXX");
</script>
Prefer no Google requests at all before consent? Gate the gtag script with data-consent="analytics" instead — Consent Mode then covers the case where it loads later. Both patterns are compliant; the gated one is stricter (no pings), Consent Mode-only preserves Google’s conversion modeling.