Google Consent Mode v2: what changed in 2024 and what you must do in 2026
Two new signals (ad_user_data, ad_personalization), Basic vs Advanced mode, and the EEA enforcement deadline — explained in plain English with a working snippet.
Since March 2024, Google requires every website that uses Google Ads or Google Analytics 4 in the European Economic Area to send Consent Mode v2 signals. Sites that don't lose conversion modeling, audience reporting, and — eventually — the ability to advertise to EEA users at all. If you skipped the migration, you're running on borrowed time.
This article explains what Consent Mode v2 actually is, how Basic and Advanced modes differ, and the minimum implementation that keeps you compliant.
What Consent Mode v2 actually does
Consent Mode is a small protocol between your website and Google's tags. Before any tag fires, you tell Google what the user has consented to via gtag('consent', 'default', …). After the user makes a choice in your banner, you call gtag('consent', 'update', …). Google's tags read these signals and adapt — for example, GA4 may collect cookieless pings instead of full hits when analytics consent is denied.
v2 introduces two new parameters that v1 didn't have:
ad_user_data— controls whether user-level data may be sent to Google for advertising.ad_personalization— controls whether the user can be added to remarketing audiences.
Together with the v1 signals (ad_storage, analytics_storage,functionality_storage, personalization_storage,security_storage), they form the seven values you must declare.
Basic mode vs Advanced mode
Both modes are valid. Pick based on how aggressive you want to be with conversion modeling.
| Aspect | Basic | Advanced |
|---|---|---|
| When tags load | Only after consent is granted | Always — but cookieless until consent |
| Conversion modeling | Lower (model uses general-public data) | Higher (model uses your own denied-consent traffic) |
| Effort to implement | Lowest | Slightly more (allow Google scripts before consent) |
| Strict-EU customers | Often preferred | Sometimes pushed back on by DPOs |
If you don't have a strong opinion, start in Basic mode. You can always upgrade later, and the difference in modeled conversions only matters above ~10k events / month.
The minimum compliant snippet
This is what every page should run before any other Google tag:
<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:'granted',
personalization_storage:'denied',
security_storage: 'granted',
wait_for_update: 500
});
</script>Then, when the user accepts marketing cookies in your banner:
gtag('consent', 'update', {
ad_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted',
analytics_storage: 'granted'
});The five mistakes I see most often
- The default block is missing. If
gtag('consent', 'default', …)doesn't run beforegtm.js, Google won't treat your site as Consent Mode at all. - The banner only updates
analytics_storageandad_storage.That's v1. v2 also needsad_user_dataandad_personalization, or your remarketing audiences will not populate. - Pre-ticked “accept all”. EEA regulators treat that as no consent. Default to denied; let the user actively opt in.
- Mixing legacy
ga.jstags. Universal Analytics is gone. If you still see__utmacookies, you've got duplicate or stale tags. - Forgetting the GTM Consent template. If you use Google Tag Manager, install a CMP template (e.g. CookieGuard's) so all your tags read the consent state automatically. Manually wiring 30 tags is a footgun.
How CookieGuard handles this for you
CookieGuard ships the consent default the moment its loader runs, so even tags that load before our UI is ready get a denied state. After the visitor decides, we map your category choices to the seven Consent Mode signals via a configurable mapping. Default mapping:
marketingcategory →ad_storage,ad_user_data,ad_personalizationanalyticscategory →analytics_storagepreferencescategory →personalization_storagenecessary→functionality_storage,security_storage(always granted)
You can override any of those if your tag taxonomy is different. The full snippet to install is two lines.