Skip to main content

Consent Mode v2

Complete implementation guide for Google Consent Mode v2, required for EU/EEA advertisers from March 2024.

What's New in v2

Additional Parameters

Consent Mode v2 introduces two new parameters:

| Parameter | Purpose | Required | |-----------|---------|----------| | ad_user_data | Consent to send user data to Google for ads | Yes (EEA) | | ad_personalization | Consent for personalized advertising | Yes (EEA) |

Complete Parameter Set

gtag('consent', 'default', {
  'ad_storage': 'denied',           // Advertising cookies
  'analytics_storage': 'denied',    // Analytics cookies
  'ad_user_data': 'denied',         // NEW: User data for ads
  'ad_personalization': 'denied',   // NEW: Personalized ads
  'wait_for_update': 500            // Wait for CMP
});

Why It Matters

EEA Requirements

Starting March 2024, for EEA users:

  • Google Ads: Cannot use audience lists without ad_user_data consent
  • Remarketing: Cannot personalize without ad_personalization consent
  • Conversion tracking: Limited without proper consent signals

Impact Without v2

| Feature | Without v2 | With v2 | |---------|-----------|---------| | Remarketing lists | Disabled | Works with consent | | Customer Match | Disabled | Works with consent | | Conversion modeling | Limited | Full capability | | Bid optimization | Impaired | Full functionality |

Implementation Guide

Step 1: Set Default State

Place this code before GTM or any Google tags:

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}

  // Set default state for all users
  gtag('consent', 'default', {
    'ad_storage': 'denied',
    'analytics_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'wait_for_update': 500
  });

  // For non-EEA users, you might grant by default
  // (Check with legal first)
  // gtag('consent', 'default', {
  //   'ad_storage': 'granted',
  //   'analytics_storage': 'granted',
  //   'ad_user_data': 'granted',
  //   'ad_personalization': 'granted',
  //   'region': ['US', 'CA']  // Only for these regions
  // });
</script>

Step 2: Update on User Consent

When user grants consent via CMP:

// User accepts all
gtag('consent', 'update', {
  'ad_storage': 'granted',
  'analytics_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'granted'
});

// User accepts analytics only
gtag('consent', 'update', {
  'analytics_storage': 'granted'
});

// User accepts ads but no personalization
gtag('consent', 'update', {
  'ad_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'denied'
});

Step 3: GTM Configuration

In Google Tag Manager:

  1. Enable Consent Overview: Settings → Container Settings → Enable consent overview
  2. Configure Google Tag: Built-in consent checks enabled by default
  3. Set Tag Consent: For each tag, specify required consent

Consent Configuration Per Tag

| Tag Type | Required Consent | |----------|------------------| | GA4 Configuration | analytics_storage | | GA4 Event | analytics_storage | | Google Ads Conversion | ad_storage | | Google Ads Remarketing | ad_storage, ad_personalization | | Floodlight | ad_storage |

CMP Integration

Supported CMPs

These CMPs have built-in Consent Mode v2 support:

| CMP | v2 Support | Integration | |-----|------------|-------------| | Cookiebot | Yes | Automatic via GTM template | | OneTrust | Yes | Manual configuration | | CookieYes | Yes | Built-in | | Usercentrics | Yes | GTM template available | | Iubenda | Yes | Manual configuration | | Termly | Yes | Built-in |

Cookiebot Example

// Cookiebot auto-updates consent via GTM template
// Or manually listen to consent events:

window.addEventListener('CookiebotOnAccept', function() {
  gtag('consent', 'update', {
    'ad_storage': Cookiebot.consent.marketing ? 'granted' : 'denied',
    'analytics_storage': Cookiebot.consent.statistics ? 'granted' : 'denied',
    'ad_user_data': Cookiebot.consent.marketing ? 'granted' : 'denied',
    'ad_personalization': Cookiebot.consent.marketing ? 'granted' : 'denied'
  });
});

OneTrust Example

// Map OneTrust categories to Consent Mode
function updateConsentFromOneTrust() {
  const activeGroups = OnetrustActiveGroups || '';

  gtag('consent', 'update', {
    'analytics_storage': activeGroups.includes('C0002') ? 'granted' : 'denied',
    'ad_storage': activeGroups.includes('C0004') ? 'granted' : 'denied',
    'ad_user_data': activeGroups.includes('C0004') ? 'granted' : 'denied',
    'ad_personalization': activeGroups.includes('C0004') ? 'granted' : 'denied'
  });
}

// Listen for OneTrust changes
window.OneTrust?.OnConsentChanged(updateConsentFromOneTrust);

Advanced Configuration

Region-Based Defaults

Apply different defaults by region:

// Strict for EEA
gtag('consent', 'default', {
  'ad_storage': 'denied',
  'analytics_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied',
  'region': ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI',
             'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU',
             'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE',
             'IS', 'LI', 'NO', 'GB']
});

// Less strict for US (opt-out model)
gtag('consent', 'default', {
  'ad_storage': 'granted',
  'analytics_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'granted',
  'region': ['US']
});

URL Passthrough

Enable conversion linking without cookies:

gtag('set', 'url_passthrough', true);
// Adds gclid/dclid to links when cookies denied

Ads Data Redaction

Redact ad click identifiers when consent denied:

gtag('set', 'ads_data_redaction', true);
// Removes ad identifiers from cookieless pings

Testing & Validation

Preview Mode Checklist

  1. Consent state visible: Check GTM preview for consent state
  2. Tags blocked correctly: Verify blocked tags when denied
  3. Updates propagate: Confirm updates trigger tags

Debug in Console

// Check current consent state
console.log(dataLayer.filter(item =>
  item[0] === 'consent'
));

// Monitor consent changes
dataLayer.push = function(original) {
  return function(item) {
    if (item[0] === 'consent') {
      console.log('Consent event:', item);
    }
    return original.apply(this, arguments);
  };
}(dataLayer.push);

Google Tag Assistant

  1. Install Tag Assistant
  2. Start recording
  3. Navigate to your site
  4. Check consent state indicators
  5. Verify tag behavior matches consent

Verification Checklist

Technical Validation

  • [ ] Default consent set before Google tags
  • [ ] All four v2 parameters included
  • [ ] wait_for_update configured
  • [ ] CMP properly updates consent
  • [ ] GTM consent overview enabled
  • [ ] Tags have correct consent requirements

Functional Validation

  • [ ] No tracking before consent granted
  • [ ] Full tracking after consent granted
  • [ ] Partial tracking with partial consent
  • [ ] Consent persists across sessions
  • [ ] Withdrawal stops tracking immediately

Google Ads Validation

  • [ ] Conversions still tracked (modeled if denied)
  • [ ] Remarketing audiences building (when consented)
  • [ ] Customer Match working (when ad_user_data granted)

Common Issues

Consent Not Updating

| Symptom | Cause | Fix | |---------|-------|-----| | Tags still blocked | Update not triggering | Check CMP callback | | Tags fire without consent | Missing default | Add default before GTM | | Inconsistent behavior | Race condition | Increase wait_for_update |

Migration Issues

If migrating from v1:

  1. Add new parameters to default
  2. Update CMP mapping
  3. Test all consent states
  4. Monitor for conversion drops

Previous: Privacy Overview Next: First-Party Data Strategy