Google Consent Mode Configuration | Blue Frog Docs

Google Consent Mode Configuration

Implement Google Consent Mode v2 for GDPR compliance and privacy-friendly tracking

Google Consent Mode Configuration

What This Means

Google Consent Mode is a framework that allows your website to adjust how Google tags (Analytics, Ads, Tag Manager) behave based on user consent choices. It enables privacy-compliant tracking by sending cookieless pings when users decline cookies, while providing conversion modeling to recover lost data. Without proper Consent Mode implementation, you face GDPR violations, blocked tracking in Europe, inaccurate conversion data, and potential fines.

Traditional Tracking (Non-Compliant):

// Loads tracking immediately, ignores consent
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
// Problem: Tracks users before consent given
// GDPR violation in EU

Consent Mode v2 (Compliant):

// 1. Set default consent state (before tags load)
gtag('consent', 'default', {
    'ad_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'analytics_storage': 'denied',
    'functionality_storage': 'denied',
    'personalization_storage': 'denied',
    'security_storage': 'granted',
    'wait_for_update': 500
});

// 2. Load tags (will use cookieless pings)
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');

// 3. Update consent after user choice
gtag('consent', 'update', {
    'ad_storage': 'granted',
    'analytics_storage': 'granted'
});
// Now tracks with cookies

Impact on Your Business

Legal Compliance:

  • GDPR requirements - Required for EU visitors
  • Avoid fines - GDPR fines up to €20M or 4% revenue
  • Privacy regulations - CCPA, PECR, ePrivacy compliance
  • User trust - Transparent data practices build credibility

Tracking Accuracy:

  • Conversion modeling - Google fills data gaps from non-consenting users
  • Better attribution - More accurate campaign performance
  • Recovered conversions - Up to 70% of lost conversions modeled
  • Cross-device tracking - Enhanced user journey understanding

Marketing Performance:

  • Ad targeting - Remarketing and custom audiences work properly
  • Campaign optimization - Google can optimize with partial data
  • ROI measurement - More accurate return on ad spend
  • Competitive advantage - Better data than competitors not using Consent Mode

Without Consent Mode:

  • Lose 40-70% of conversions in EU (no consent = no tracking)
  • Blind spot in marketing attribution
  • Can't optimize ad campaigns properly
  • Risk of GDPR fines and legal action

How to Diagnose

Method 1: Google Tag Assistant

  1. Install Tag Assistant
  2. Visit your website
  3. Click Tag Assistant icon
  4. Check Consent tab

What to Look For:

Properly configured:

Consent Mode Status: ✓ Implemented
Initial consent state: Denied
User consent: Granted after banner acceptance
Consent parameters detected:
- ad_storage: denied → granted
- analytics_storage: denied → granted

Not configured:

Consent Mode Status: ✗ Not detected
Tags firing before consent

Method 2: Browser DevTools Console

Check consent state:

// Open DevTools console
// Type this command:
dataLayer

// Look for consent commands:
[
    ['consent', 'default', {
        ad_storage: 'denied',
        analytics_storage: 'denied'
    }],
    ['js', Date],
    ['config', 'G-XXXXXXXXXX']
]

// Verify consent default fired BEFORE config

Method 3: Network Tab Inspection

  1. Open DevTools (F12)
  2. Go to Network tab
  3. Filter by google-analytics.com or googletagmanager.com
  4. Look at request parameters

Check for:

❌ WITHOUT Consent Mode:
Request to: /collect?v=1&tid=G-XXX&...
No consent parameters

✅ WITH Consent Mode:
Request to: /g/collect?v=2&tid=G-XXX&gcs=G100&...
gcs parameter present (consent state)

Consent states:
G100 = all denied
G110 = analytics granted, ads denied
G111 = all granted

Method 4: Google Analytics 4 DebugView

  1. Enable debug mode:
gtag('config', 'G-XXXXXXXXXX', {
    'debug_mode': true
});
  1. Go to GA4 → ConfigureDebugView
  2. Trigger events on your site
  3. Check event parameters

Look For:

Event: page_view
Parameters:
- gcs: G100 (consent state)
- consent_ad_storage: denied
- consent_analytics_storage: denied

If using CMP (Cookiebot, OneTrust, etc.):

  1. Open cookie banner
  2. Check settings
  3. Accept/reject cookies
  4. Verify gtag('consent', 'update', ...) fires

Test:

  • Does banner appear on first visit?
  • Can users customize preferences?
  • Does acceptance trigger consent update?
  • Are choices remembered?

General Fixes

Add to <head> BEFORE any tracking scripts:

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

// Set default consent state (BEFORE any tags load)
gtag('consent', 'default', {
    'ad_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'analytics_storage': 'denied',
    'functionality_storage': 'denied',
    'personalization_storage': 'denied',
    'security_storage': 'granted', // Always allowed
    'wait_for_update': 500 // Wait 500ms for consent choice
});

// Region-specific defaults (optional)
gtag('consent', 'default', {
    'ad_storage': 'denied',
    'analytics_storage': 'denied',
    'region': ['BE', 'BG', 'CZ', 'DK', 'DE', 'EE', 'IE', 'EL', 'ES', 'FR', 'HR', 'IT', 'CY', 'LV', 'LT', 'LU', 'HU', 'MT', 'NL', 'AT', 'PL', 'PT', 'RO', 'SI', 'SK', 'FI', 'SE', 'GB', 'IS', 'LI', 'NO', 'CH']
});

// Non-EEA countries can have analytics_storage granted by default
gtag('consent', 'default', {
    'analytics_storage': 'granted',
    'region': ['US', 'CA', 'AU']
});
</script>

<!-- NOW load Google Tag Manager -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>

When user accepts cookies:

// User clicks "Accept All" button
document.getElementById('accept-cookies').addEventListener('click', function() {
    gtag('consent', 'update', {
        'ad_storage': 'granted',
        'ad_user_data': 'granted',
        'ad_personalization': 'granted',
        'analytics_storage': 'granted',
        'functionality_storage': 'granted',
        'personalization_storage': 'granted'
    });

    // Hide cookie banner
    document.getElementById('cookie-banner').style.display = 'none';

    // Save choice to localStorage
    localStorage.setItem('consent', 'granted');
});

// User clicks "Reject All" button
document.getElementById('reject-cookies').addEventListener('click', function() {
    // Consent stays denied (already set in default)
    gtag('consent', 'update', {
        'ad_storage': 'denied',
        'ad_user_data': 'denied',
        'ad_personalization': 'denied',
        'analytics_storage': 'denied'
    });

    document.getElementById('cookie-banner').style.display = 'none';
    localStorage.setItem('consent', 'denied');
});

Check for existing consent on page load:

// On page load, check if user already made choice
window.addEventListener('DOMContentLoaded', function() {
    const consent = localStorage.getItem('consent');

    if (consent === 'granted') {
        // User previously accepted
        gtag('consent', 'update', {
            'ad_storage': 'granted',
            'analytics_storage': 'granted'
        });
        // Don't show banner
    } else if (consent === 'denied') {
        // User previously rejected
        // Keep default denied state
        // Don't show banner
    } else {
        // No previous choice - show banner
        document.getElementById('cookie-banner').style.display = 'block';
    }
});

Fix 4: Integrate with Cookiebot

Cookiebot Consent Mode integration:

<script id="Cookiebot" src="https://consent.cookiebot.com/uc.js" data-cbid="YOUR-COOKIEBOT-ID" data-blockingmode="auto" type="text/javascript"></script>

<script>
window.addEventListener('CookiebotOnConsentReady', function() {
    // Update consent based on Cookiebot choices
    gtag('consent', 'update', {
        'ad_storage': Cookiebot.consent.marketing ? 'granted' : 'denied',
        'ad_user_data': Cookiebot.consent.marketing ? 'granted' : 'denied',
        'ad_personalization': Cookiebot.consent.marketing ? 'granted' : 'denied',
        'analytics_storage': Cookiebot.consent.statistics ? 'granted' : 'denied',
        'functionality_storage': Cookiebot.consent.preferences ? 'granted' : 'denied',
        'personalization_storage': Cookiebot.consent.preferences ? 'granted' : 'denied'
    });
});
</script>

Fix 5: Integrate with OneTrust

OneTrust Consent Mode integration:

function OptanonWrapper() {
    // OneTrust callback function
    const groups = OnetrustActiveGroups;

    gtag('consent', 'update', {
        'ad_storage': groups.includes('C0004') ? 'granted' : 'denied',
        'analytics_storage': groups.includes('C0002') ? 'granted' : 'denied',
        'functionality_storage': groups.includes('C0003') ? 'granted' : 'denied',
        'personalization_storage': groups.includes('C0003') ? 'granted' : 'denied'
    });
}

Fix 6: Google Tag Manager Implementation

GTM Consent Mode setup:

  1. Create Custom HTML tag
  2. Set to fire on Consent Initialization - All Pages
  3. Add consent default code:
<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': 'denied',
    'personalization_storage': 'denied',
    'security_storage': 'granted',
    'wait_for_update': 2000
});
</script>
  1. Create triggers for consent update
  2. Link to your consent banner acceptance

Fix 7: URL Passthrough for Ad Clicks

Enable ad click information without cookies:

gtag('consent', 'default', {
    'ad_storage': 'denied',
    'analytics_storage': 'denied',
    'url_passthrough': true, // Pass click IDs in URL
    'ads_data_redaction': true // Redact ads data
});

What this does:

  • Passes GCLID, DCLID, etc. in URLs
  • Allows conversion tracking without cookies
  • Redacts user data in requests

Fix 8: WordPress Implementation

Using cookie banner plugin with Consent Mode:

// Add to theme functions.php or custom plugin

add_action('wp_head', 'add_consent_mode', 1);
function add_consent_mode() {
    ?>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}

    gtag('consent', 'default', {
        'ad_storage': 'denied',
        'analytics_storage': 'denied',
        'wait_for_update': 500
    });
    </script>
    <?php
}

// Listen for consent changes (depends on your cookie plugin)
add_action('wp_footer', 'consent_update_script');
function consent_update_script() {
    ?>
    <script>
    // Example for custom cookie banner
    jQuery(document).on('cookie_consent_accepted', function() {
        gtag('consent', 'update', {
            'ad_storage': 'granted',
            'analytics_storage': 'granted'
        });
    });
    </script>
    <?php
}

Platform-Specific Guides

Detailed implementation instructions for your specific platform:

Platform Troubleshooting Guide
Shopify Shopify Consent Mode Guide
WordPress WordPress Consent Mode Guide
Wix Wix Consent Mode Guide
Squarespace Squarespace Consent Mode Guide
Webflow Webflow Consent Mode Guide

Verification

After implementing Consent Mode:

Test 1: Tag Assistant

  1. Open Tag Assistant
  2. Visit your site
  3. Verify "Consent Mode: Implemented"
  4. Check default state is "denied"
  5. Accept cookies
  6. Verify state changes to "granted"

Test 2: Network Requests

  1. Open DevTools Network tab
  2. Reload page
  3. Check Google Analytics requests
  4. Look for gcs=G100 parameter (denied state)
  5. Accept cookies
  6. Check for gcs=G111 (granted state)

Test 3: GA4 Real-Time Report

  1. Go to GA4 Real-Time report
  2. Visit your site from different browser
  3. Don't accept cookies
  4. Should see cookieless ping (modeling data)
  5. Accept cookies
  6. Should see full tracking data

Test 4: Test from EU IP

  1. Use VPN to simulate EU visitor
  2. Verify consent banner shows
  3. Verify default consent is denied
  4. Test acceptance/rejection flows

Common Mistakes

  1. Loading tags before consent default - Must set consent FIRST
  2. Not using Consent Mode v2 - v1 missing required parameters
  3. Forgetting security_storage: granted - Security features should work
  4. No wait_for_update - Tags fire before user can respond
  5. Not saving user choice - Banner shows on every page
  6. Granting by default in EU - GDPR violation
  7. Not testing both states - Test accept AND reject
  8. Forgetting URL passthrough - Lose ad attribution data

Further Reading

// SYS.FOOTER