Skip to content

CMP Integration with Consent Mode

A Consent Management Platform (CMP) does three things: shows users a consent banner, records their choices, and provides a mechanism to communicate those choices to your tags. The last part — communicating choices to GTM — is what CMP integration means in practice.

This article covers the integration patterns for the most common CMPs and how to verify the connection is working correctly.

When a user interacts with a consent banner, the CMP needs to:

  1. Record the user’s choice (in a cookie, localStorage, or server-side)
  2. Call gtag('consent', 'update', {...}) with the appropriate consent types
  3. This update propagates through GTM to all tags that check consent state

The CMP integration is responsible for step 2. Without it, GTM never learns about the user’s consent choice and tags either fire without consent (if defaults are granted) or never fire (if defaults are denied).

Section titled “Integration approach 1: Community Template Gallery”

Most major CMPs publish official GTM templates to the Community Template Gallery. This is the recommended approach for most implementations because:

  • Templates handle the consent update automatically
  • The integration is maintained by the CMP vendor
  • You don’t need to write custom JavaScript
  • Updates are versioned and can be pulled when the CMP updates its API

To install a CMP template:

  1. In GTM, go to Templates → Search Gallery
  2. Search for your CMP name
  3. Add the template to your workspace
  4. Create a tag using the template, configure your CMP account ID
  5. Set the trigger to Consent Initialization — All Pages

Integration approach 2: CMP callback in custom code

Section titled “Integration approach 2: CMP callback in custom code”

For CMPs without a Gallery template, or when you need custom control, call the consent update from your CMP’s JavaScript callback. The general pattern:

// Generic CMP callback pattern
// Replace with your CMP's actual callback mechanism
myCMP.onConsentUpdate(function(consentObject) {
gtag('consent', 'update', {
'analytics_storage': consentObject.analytics ? 'granted' : 'denied',
'ad_storage': consentObject.advertising ? 'granted' : 'denied',
'ad_user_data': consentObject.advertising ? 'granted' : 'denied',
'ad_personalization': consentObject.advertising ? 'granted' : 'denied',
'functionality_storage': consentObject.functional ? 'granted' : 'denied',
'personalization_storage': consentObject.personalization ? 'granted' : 'denied'
});
});

Google maintains an official CMP Partner Program that certifies CMPs for Consent Mode v2 compliance. Partners have completed Google’s integration requirements and follow best practices for consent signal passing.

Google CMP Partner Program: cmppartnerprogram.withgoogle.com

Check this list to see which CMPs are officially certified. Certified partners have been tested by Google and follow standardized approaches to consent signal collection and updating. If you are selecting a new CMP, choosing a certified partner reduces integration risk.

Certified CMP partners include (this list grows; check the official program for current status):

  • Cookiebot (by Usercentrics)
  • OneTrust
  • Usercentrics
  • CookieYes
  • Iubenda
  • And many others

Cookiebot (now Usercentrics Cookiebot) integrates via its official GTM template or via the CookiebotOnAccept / CookiebotOnDecline callback functions.

Via Gallery template:

  1. Search Gallery for “Cookiebot” (published by Usercentrics)
  2. Install and create a tag with your Cookiebot Domain Group ID
  3. Fire on Consent Initialization — All Pages

Via JavaScript callback:

// Add to your page (or a Custom HTML tag on Consent Initialization)
window.addEventListener('CookiebotOnLoad', function() {
gtag('consent', 'update', {
'analytics_storage': Cookiebot.consent.statistics ? 'granted' : 'denied',
'ad_storage': Cookiebot.consent.marketing ? 'granted' : 'denied',
'ad_user_data': Cookiebot.consent.marketing ? 'granted' : 'denied',
'ad_personalization': Cookiebot.consent.marketing ? 'granted' : 'denied',
'functionality_storage': Cookiebot.consent.preferences ? 'granted' : 'denied'
});
});
window.addEventListener('CookiebotOnAccept', function() {
gtag('consent', 'update', {
'analytics_storage': Cookiebot.consent.statistics ? 'granted' : 'denied',
'ad_storage': Cookiebot.consent.marketing ? 'granted' : 'denied',
'ad_user_data': Cookiebot.consent.marketing ? 'granted' : 'denied',
'ad_personalization': Cookiebot.consent.marketing ? 'granted' : 'denied',
'functionality_storage': Cookiebot.consent.preferences ? 'granted' : 'denied'
});
});
window.addEventListener('CookiebotOnDecline', function() {
gtag('consent', 'update', {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'functionality_storage': 'denied'
});
});

Cookiebot categories: statistics → analytics_storage, marketing → ad_storage/ad_user_data/ad_personalization, preferences → functionality_storage.

Returning visitors already have a consent choice stored. The CMP should fire its callback immediately on page load to restore the previous consent state — before the wait_for_update timeout expires.

Verify this works:

  1. Grant consent on a test page
  2. Close the browser tab
  3. Reopen the same URL
  4. Check GTM Preview mode — the consent update should appear near the beginning of the event stream, before your GA4 or Ads tags fire

If returning visitors hit the timeout instead, your CMP is reading its cookie too slowly. Check whether the CMP loads synchronously or asynchronously and whether there is a race condition with the cookie read.

Browser cookie check: After granting consent, open DevTools → Application → Cookies. You should see:

  • _ga and _ga_XXXX cookies: analytics consent granted
  • _gcl_au cookie: ad_storage granted
  • Your CMP’s own consent cookie (e.g., CookieConsent for Cookiebot)

GTM Preview mode: Open the Consent tab on any event after the consent update fires. All required types should show granted.

Network tab: After granting consent, check for requests to www.google-analytics.com/g/collect. With analytics_storage: denied, the request URL will include &gcs=G100 (consent denied signal). With granted, it will include &gcs=G111.

Console verification:

// Run in browser console to see current consent state
window.google_tag_data?.ics?.entries

CMP fires its callback asynchronously after a script loads. Many CMPs load their script asynchronously, meaning the callback doesn’t fire until after the DOM is ready or a network request completes. If the wait_for_update timeout fires before the CMP callback, tags fire with the default denied state. Increase wait_for_update or switch to the inline consent default approach.

Mismatching category names. CMP consent categories have different names across platforms. Always map CMP categories to Consent Mode types carefully. A typo like analytics vs Analytics can mean consent is never granted.

Not handling the “consent restored from cookie” case. Many implementations only handle onAccept and onDecline but not the page-load restoration case. Returning visitors may never trigger a consent update, leaving tags in their default state.

Testing in the same browser session that already has consent. Always test consent flows in an incognito window or after clearing cookies.