Google Consent Mode v2 is mandatory in the EEA for GA4 and Google Ads since March 2024. Instead of blocking GA4 until consent, you load it immediately with denied defaults — GA4 then models conversions for users who decline, preserving campaign signal quality.
analytics_storage: 'denied' and ad_storage: 'denied' by defaultwait_for_update: 500 gives cookie-warn time to fire before GA4's first eventanalytics category → analytics_storagemarketing category → ad_storage + ad_user_data + ad_personalization| Signal | State | Set by |
|---|---|---|
| analytics_storage | denied | default |
| ad_storage | denied | default |
| ad_user_data | denied | default |
| ad_personalization | denied | default |
| functionality_storage | granted | default (always) |
<head>
<!-- STEP 1: gtag defaults — denied before GA4 loads -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('consent', 'default', {
analytics_storage: 'denied',
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
functionality_storage: 'granted',
wait_for_update: 500
});
gtag('js', new Date());
</script>
<!-- STEP 2: Load GA4 (respects denied defaults above) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>gtag('config', 'G-XXXXXXXXXX');</script>
<!-- STEP 3: cookie-warn with analytics + marketing categories -->
<script
id="cookieScript"
data-lang-en="{
'text': 'We use cookies to improve your experience.',
'accept_text': 'Accept all',
'accept_selected_text': 'Save settings',
'reject_text': 'Necessary only',
'categories': {
'necessary': {'label': 'Necessary', 'description': 'Required for the site to function.', 'required': true},
'analytics': {'label': 'Analytics', 'description': 'Google Analytics.'},
'marketing': {'label': 'Marketing', 'description': 'Google Ads — personalised ads and conversion tracking.'}
}
}"
data-callback="cookieWarnCallback"
src="cookie-warn.min.js">
</script>
</head>
<script>
function cookieWarnCallback(accepted, categories) {
if (!categories) {
gtag('consent', 'update', {
analytics_storage: accepted ? 'granted' : 'denied'
});
return;
}
gtag('consent', 'update', {
analytics_storage: categories.analytics ? 'granted' : 'denied',
ad_storage: categories.marketing ? 'granted' : 'denied',
ad_user_data: categories.marketing ? 'granted' : 'denied',
ad_personalization: categories.marketing ? 'granted' : 'denied'
});
}
</script>