Skins4You
Tracking · GDPR · May 2026

Google Consent Mode v2 Setup

Default-deny, update on consent, GA4 integration. With code snippets, pitfalls and our own setup as a template.

9 min read · by Edgar Oganisjan

Since March 2024, Google Consent Mode v2 has been mandatory if you use Google ad products (Ads, Floodlight, GA4 audiences) in the EEA. Without correct setup, GA4 reports run empty and Ads audiences collapse. What it is, how it works technically, and how to set it up correctly in under 30 minutes – with the code we use on this site.

What is Consent Mode v2?

Consent Mode is Googles answer to European data protection. Before each data transfer, the browser tag is told whether the user consented. Without consent, Google sends only cookieless pings – aggregated, anonymised signals. Compliant and still gives you rough reach numbers via modeling.

Version 2 adds two new signals: ad_user_data and ad_personalization – mandatory for every advertiser in the EEA.

Step 1: Default-deny before any GA4 call

Before gtag loads, set defaults. Important: before loading, otherwise tags fire with unintended settings.

<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',
  'security_storage': 'granted',
  'wait_for_update': 500
});
</script>

Step 2: Load GA4 deferred

Only after consent in the statistics category, inject GA4 dynamically:

const GA4_ID = 'G-XXXXXXXXXX';
function loadAnalytics(consent){
  if(!consent || !consent.statistics) return;
  if(window._ga4Loaded) return;
  window._ga4Loaded = true;
  const s = document.createElement('script');
  s.async = true;
  s.src = 'https://www.googletagmanager.com/gtag/js?id=' + GA4_ID;
  document.head.appendChild(s);
  gtag('js', new Date());
  gtag('config', GA4_ID, { 'anonymize_ip': true });
}

Step 3: Update on consent

function applyConsent(consent){
  gtag('consent', 'update', {
    'analytics_storage': consent.statistics ? 'granted' : 'denied',
    'ad_storage': consent.marketing ? 'granted' : 'denied',
    'ad_user_data': consent.marketing ? 'granted' : 'denied',
    'ad_personalization': consent.marketing ? 'granted' : 'denied'
  });
  loadAnalytics(consent);
}

Step 4: Persistent storage

Store consent in localStorage (not cookie, since cookies must be deleted after 13 months):

{
  "necessary": true,
  "statistics": true,
  "marketing": false,
  "ts": 1715342400000
}

Common pitfalls

  • Wrong order: default-set after gtag = tags fire with wrong defaults.
  • Missing update: after "Accept" click, no update sent → modeling stays disabled.
  • Cookie instead of localStorage: cookie auto-deleted after 6–13 months → banner reappears.
  • Skipping ad_user_data / ad_personalization: works for analytics but blocks Ads audiences.
  • Testing with adblocker: always test in clean browser without extensions.

How to test

  1. Open in incognito, reject banner → Network tab shows pings to collect? with gcs=G100 (= denied).
  2. Accept banner → pings have gcs=G111 (= all granted).
  3. In GA4 → Admin → Data settings should show "Consent Mode active".

Bottom line

Consent Mode v2 is conceptually simple but tricky in detail. Done right, you keep GDPR compliance and usable tracking. Ignored, you risk ad effectiveness loss and fines.

About the author

Edgar Oganisjan is the founder of Skins4You – a web design and online marketing agency from Graz, Austria. More about the team →