LW IT Solutions
« Blog Overview /Digital Analytics / How to Implement Google Consent Mode v2
This post in other languages:

How to Implement Google Consent Mode v2

Part 1 of 4 in the series Wiring consent correctly

How to Implement Google Consent Mode v2
Contents
  1. Why is Consent Mode v2 So Crucial?
  2. Method 1: Implementing via Google Tag Manager (GTM)
  3. Method 2: Implementing via Vanilla JavaScript (Directly)
  4. Summary
  5. Checking the Signals and Keeping Ad Clicks Without Cookies
  6. Questions and answers
  7. Sources

For anyone operating within the European Economic Area (EEA) or handling data from European users, Google Consent Mode v2 is no longer a “nice-to-have” feature—it is a strict requirement as of March 2024. Driven by the Digital Markets Act (DMA), Google has fundamentally changed how its advertising and analytics platforms process data.

Failing to implement Consent Mode v2 means bidding farewell to remarketing capabilities and watching conversion tracking severely degrade. As data architects, our goal is to maintain data fidelity while strictly adhering to privacy protocols. Here is a deep dive into why Consent Mode v2 matters, how it impacts the GMP stack, and how to implement it correctly.

Why is Consent Mode v2 So Crucial?

At its core, Consent Mode bridges the gap between user privacy choices and the data collection systems. When a user interacts with the cookie banner, Consent Mode communicates their choices (granted or denied) to Google’s tags.

The introduction of v2 brought two critical new parameters specifically targeting advertising:

  1. ad_user_data: Sets consent for sending user data to Google for advertising purposes.
  2. ad_personalization: Sets consent for personalized advertising (remarketing).

What It Does for Google Tags (Ads, Floodlights, SA360, GA4)

When properly configured in Advanced Consent Mode, tags load before the user makes a choice, but they drastically change their behavior based on the consent state:

  • Google Analytics 4 (GA4): If analytics_storage is denied, GA4 stops reading or writing cookies. Instead, it sends cookieless “pings.” GA4 then uses machine learning to bridge the gap through Behavioral Modeling, which surfaces estimated user journeys without compromising privacy.
  • Google Ads & SA360: If ad_storage or ad_user_data is denied, advertising tags send cookieless conversion pings. Google’s engine then utilizes Conversion Modeling to recover lost conversions, ensuring ROAS calculations and automated bidding algorithms don’t collapse.
  • Floodlights (Campaign Manager 360): Similar to Google Ads, Floodlight tags respect the consent state, utilizing aggregate data and modeling to attribute conversions accurately across display and video campaigns without relying on third-party cookies.

Without v2, Google will simply drop unconsented data, crippling measurement and audience building.

Diagram for the article: What It Does for Google Tags, Use a Consent Management Platform (CMP) Template or…, Configure Tag Consent Settings …
The sequence from the article in 5 steps: What It Does for Google Tags, Use a Consent Management Platform (CMP) Template or…, Configure Tag Consent Settings, The Default State ….

Method 1: Implementing via Google Tag Manager (GTM)

For most setups, GTM is the cleanest way to manage consent. It acts as the central nervous system for the tracking architecture.

Step 1: Enable Consent Overview

  1. Go to the GTM Workspace.
  2. Navigate to Admin > Container Settings.
  3. Check the box for Enable consent overview. This unlocks a shield icon in the Tags view, which makes consent settings easy to manage across all tags.

Step 2: Use a Consent Management Platform (CMP) Template or a Consent Mode Template

Instead of building a custom logic, utilize a certified CMP (like Cookiebot, OneTrust, or CookieYes) from the GTM Community Template Gallery.

  1. Add the CMP template to the workspace.
  2. Configure it with the CMP ID.
  3. Set the trigger to Consent Initialization – All Pages. This is a special trigger that fires before standard Page Views, ensuring consent defaults are set before any Google Tags fire.

If the CMP is implemented directly into the website, I recommend using the Template “gtm-templates-simo-ahava” from Simo Ahava as it is always up to date and brings the best functionality.

For Consent Mode to work, add two instances of the Template as Tags.

  1. Default Tag: Fire on Consent Initialization – All Pages and set up everything to “Denied”.
  2. Update Tag: Fire on Consent Update from the CMP. Set the Parameters accoring the user’s choices.

Step 3: Configure Tag Consent Settings

Google Tags (GA4, Google Ads) have built-in consent checks. There is no need to block them from firing. Instead:

  1. Open the GA4 or Google Ads tag.
  2. Go to Advanced Settings > Consent Settings.
  3. Ensure it requires ad_storage and/or analytics_storage.
  4. The tag will handle the rest—firing normally if granted, or sending cookieless pings if denied.

Method 2: Implementing via Vanilla JavaScript (Directly)

For a custom, highly optimized frontend or a Single Page Application (SPA) where GTM is too heavy, implementing Consent Mode directly via vanilla JS is the way to go.

This requires two distinct steps: setting the Default state before tags load, and sending an Update state when the user interacts with the banner.

1. The Default State (Place in <head>)

This script must execute before the global site tag (gtag.js). It tells Google to assume everything is denied by default (for EEA users).

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

  // Set default consent to 'denied' for all parameters
  gtag('consent', 'default', {
    'ad_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'analytics_storage': 'denied',
    'wait_for_update': 500 // Gives the CMP 500ms to load before tags fire
  });
</script>

<!-- Now load your standard gtag.js script below this -->
<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>

2. The Update State (Triggered by User Action)

When the user clicks “Accept” (or customizes their choices) on the cookie banner, that event has to be captured and pushed as an update to the dataLayer.

Here is an example of an event listener attached to a custom banner’s “Accept All” button:

document.getElementById('btn-accept-all').addEventListener('click', function() {
  
  // Push the updated consent state to Google
  gtag('consent', 'update', {
    'ad_storage': 'granted',
    'ad_user_data': 'granted',
    'ad_personalization': 'granted',
    'analytics_storage': 'granted'
  });

  // Hide the banner and save the preference in your own local cookie
  document.getElementById('cookie-banner').style.display = 'none';
  setCookie('user_consent_saved', 'true', 365);
});

If necessary, adjust the ID of the Button “btn-accept-all”.

Summary

Implementing Google Consent Mode v2 is the definitive way to future-proof the digital analytics and advertising infrastructure. Whether deploying through GTM’s streamlined interface or hardcoding it via vanilla JavaScript for maximum performance, setting proper default and update states ensures legal compliance while empowering Google’s machine learning to recover lost data.

Checking the Signals and Keeping Ad Clicks Without Cookies

Whether the default and update commands arrive as intended can be checked in Tag Assistant, which GTM’s Preview mode opens. In the Summary, the earliest Consent event shows the default state under API Call, with the parameters ad_storage, ad_user_data, ad_personalization and analytics_storage. After a choice in the banner, the most recent Consent event has to show the updated values. The Consent tab in the Output section summarises both in the columns On-page Default and On-page Update.

URL Passthrough

After an ad click, information about the click can be appended to the landing page URL as a query parameter. It is normally stored in first-party cookies, which is not possible while ad_storage is denied. URL passthrough carries it in the URL instead: internal links can then receive the parameters gclid, dclid, gclsrc, _gl and wbraid.

gtag('set', 'url_passthrough', true);

In GTM, the same is done with a url_passthrough field set to true in the Google tag. Google lists the conditions: a consent-aware Google tag on the page, consent mode implemented, an outgoing link to the same domain as the current page and, for Google Ads and Floodlight tags, a GCLID or DCLID in the URL. Redirects have to keep the parameters, analytics reports should ignore them in page URLs, and pages whose content depends on query parameters have to tolerate them.

A related setting is gtag('set', 'ads_data_redaction', true): while ad_storage is denied, Google Ads and Floodlight tags then redact ad click identifiers in their network requests.

Questions and answers

What determines the right value for wait_for_update when visitors often take a few seconds to decide?

The value does not wait for the decision; it waits for the CMP. It tells the Google tags how long to hold off for a possible update before they proceed with the default state. What it covers is the load time of the banner script, not the time a visitor spends thinking beforehand.

That is also why a generous value improves nothing. Setting it to ten seconds delays every measurement by ten seconds for everyone who never clicks at all, and a decision made later is passed on through update anyway and takes effect from that moment.

A measured value is therefore more useful than an estimated one: the Network tab shows when the CMP script has finished loading, and the value should sit just above that point. The 500 milliseconds in the example correspond to the minimum Google suggests once network requests are involved; more only pays off when the measurement calls for it. Anything beyond that merely pushes back the cookieless pings that would otherwise already be on their way.

Does it do any harm to additionally block the GA4 tag with an exception when consent is missing?

Yes, and invisibly so. A hard-blocked tag sends nothing at all, not even a cookieless ping.

Those pings, however, are the data that the modeling relies on to make up for the missing cookies. The container then formally runs Advanced Consent Mode while delivering the data of the basic mode: the consent settings in the tag are in place, the modeling still has nothing to work with, and the reports simply lack the share of visitors who declined.

Verifying this takes a few minutes. After declining consent in a private window, Advanced Consent Mode still sends a request to google-analytics.com, only without identifiers. If no request goes out at all, the exception is still in effect, and it should be removed without replacement: the built-in consent check in the tag does the same job without suppressing the pings.

Wiring consent correctly

  1. How to Implement Google Consent Mode v2
  2. How Cookieless Pings Work in Google Consent Mode
  3. GA4 Consent Mode v2: The gcd Parameter, CMP Race Conditions and Server-Side Debugging
  4. How to Pass Consent Status to Server-Side GTM
Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

Write a comment

Differing figures from other accounts and questions about the setup are welcome here.

The email address is not published. Required fields are marked with an asterisk.

ALL ARTICLES & CATEGORIES

CCTV

Follow this category by RSS

Cloud & AI

Follow this category by RSS

Data Privacy

All 18 articles in this category Follow this category by RSS

Digital Analytics

All 58 articles in this category Follow this category by RSS

Digital Marketing

All 37 articles in this category Follow this category by RSS

IT & Networks

All 17 articles in this category Follow this category by RSS

Music Production

All 16 articles in this category Follow this category by RSS

Raspberry PI

Follow this category by RSS

Smart Home

All 18 articles in this category Follow this category by RSS

Web Development

All 11 articles in this category Follow this category by RSS

WordPress Plugins & Tricks

All 12 articles in this category Follow this category by RSS