CMP Integration
Complete guide to integrating Consent Management Platforms with Google Tag Manager for compliant analytics and marketing tracking.
What is a CMP?
A Consent Management Platform (CMP) handles:
- Cookie consent banners
- User preference storage
- Consent signal distribution
- Compliance documentation
Popular CMPs
| CMP | Pricing | Best For | |-----|---------|----------| | Cookiebot | From $0/mo | SMB, easy setup | | OneTrust | Custom | Enterprise | | CookieYes | From $0/mo | Small sites | | Usercentrics | From $49/mo | Mid-market | | Termly | From $0/mo | Basic needs | | Iubenda | From $29/yr | Multi-site | | Osano | From $199/mo | US companies |
Cookiebot Integration
Step 1: Account Setup
- Create account at cookiebot.com
- Add your domain
- Run initial scan
- Categorize cookies
Step 2: GTM Implementation
Use the official Cookiebot GTM template:
- In GTM, go to Templates → Search Gallery
- Search "Cookiebot CMP"
- Add template to workspace
Step 3: Create Cookiebot Tag
| Setting | Value | |---------|-------| | Tag Type | Cookiebot CMP | | Cookiebot ID | Your CBID | | Mode | Auto (recommended) | | Trigger | Consent Initialization - All Pages |
Step 4: Consent Mode Integration
The Cookiebot template auto-updates consent. Verify settings:
// Default consent (set by Cookiebot before GTM)
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied'
});
Step 5: GTM Consent Overview
Enable in GTM:
- Admin → Container Settings
- Enable Consent Overview
- Configure built-in consent checks
Cookiebot Consent Mapping
| Cookiebot Category | Consent Mode Signal | |--------------------|---------------------| | necessary | Always allowed | | statistics | analytics_storage | | marketing | ad_storage, ad_user_data | | preferences | functionality_storage |
OneTrust Integration
Step 1: OneTrust Setup
- Configure cookie categories in OneTrust dashboard
- Generate script snippet
- Note your data domain URL
Step 2: GTM Implementation
<!-- Place in page <head> BEFORE GTM -->
<script>
// OneTrust Consent
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
// Set defaults
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'wait_for_update': 500
});
</script>
<!-- OneTrust Auto-Blocking Script -->
<script
src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js"
data-domain-script="YOUR-DOMAIN-ID">
</script>
Step 3: Consent Update Handler
Create a GTM tag to handle consent updates:
// Custom HTML Tag - OneTrust Consent Handler
(function() {
function updateConsentState() {
var groups = window.OnetrustActiveGroups || '';
gtag('consent', 'update', {
'analytics_storage': groups.indexOf('C0002') > -1 ? 'granted' : 'denied',
'ad_storage': groups.indexOf('C0004') > -1 ? 'granted' : 'denied',
'ad_user_data': groups.indexOf('C0004') > -1 ? 'granted' : 'denied',
'ad_personalization': groups.indexOf('C0004') > -1 ? 'granted' : 'denied',
'functionality_storage': groups.indexOf('C0003') > -1 ? 'granted' : 'denied',
'personalization_storage': groups.indexOf('C0003') > -1 ? 'granted' : 'denied'
});
}
// Initial update
if (window.OnetrustActiveGroups) {
updateConsentState();
}
// Listen for changes
window.OneTrust = window.OneTrust || {};
window.OneTrust.OnConsentChanged = updateConsentState;
})();
OneTrust Category Mapping
| OneTrust Category | ID | Consent Mode Signal | |-------------------|-----|---------------------| | Strictly Necessary | C0001 | Always allowed | | Performance | C0002 | analytics_storage | | Functional | C0003 | functionality_storage | | Targeting | C0004 | ad_storage, ad_user_data |
CookieYes Integration
Step 1: Setup
- Create account at cookieyes.com
- Add domain and scan
- Get installation script
Step 2: GTM Implementation
CookieYes supports GTM template or direct integration:
<!-- Before GTM -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied'
});
</script>
<!-- CookieYes Script -->
<script id="cookieyes" type="text/javascript" src="https://cdn-cookieyes.com/client_data/YOUR_ID/script.js"></script>
Step 3: GTM Triggers
Create triggers based on CookieYes events:
| Trigger | Event Name | Purpose | |---------|------------|---------| | CY Analytics Consent | cookieyes_consent_update | Fire analytics | | CY Marketing Consent | cookieyes_consent_update | Fire marketing |
Filter with condition:
Variable: {{CookieYes Analytics Consent}}
Equals: yes
Universal Consent Handler
Custom Implementation
For any CMP, create a universal handler:
// Consent Handler - Works with any CMP
(function() {
'use strict';
window.ConsentHandler = {
// Current state
state: {
analytics: false,
marketing: false,
personalization: false
},
// Update consent and notify GTM
update: function(newState) {
this.state = Object.assign(this.state, newState);
gtag('consent', 'update', {
'analytics_storage': this.state.analytics ? 'granted' : 'denied',
'ad_storage': this.state.marketing ? 'granted' : 'denied',
'ad_user_data': this.state.marketing ? 'granted' : 'denied',
'ad_personalization': this.state.personalization ? 'granted' : 'denied'
});
// Also push data layer event for custom triggers
dataLayer.push({
event: 'consent_updated',
consent_analytics: this.state.analytics,
consent_marketing: this.state.marketing,
consent_personalization: this.state.personalization
});
}
};
// Example: Hook into your CMP's callback
// YourCMP.onConsentChange(function(consent) {
// ConsentHandler.update({
// analytics: consent.analytics,
// marketing: consent.marketing,
// personalization: consent.personalization
// });
// });
})();
Testing Consent Integration
GTM Preview Mode
- Start GTM Preview
- Load page
- Check Consent tab in debugger
- Verify initial state = denied
- Accept cookies
- Verify state = granted
- Confirm blocked tags now fire
Browser Testing
// Check current consent state
dataLayer.filter(item => item[0] === 'consent')
// Check CMP state
// Cookiebot
Cookiebot.consent
// OneTrust
OnetrustActiveGroups
// CookieYes
getCookie('cookieyes-consent')
Validation Checklist
- [ ] Default state is denied for EEA users
- [ ] Banner appears on first visit
- [ ] Consent persists across sessions
- [ ] Tags block correctly when denied
- [ ] Tags fire correctly when granted
- [ ] Consent update triggers immediately
- [ ] Mobile/responsive banner works
Common Issues
Banner Not Appearing
| Cause | Solution | |-------|----------| | Script blocked | Check CSP headers | | Async loading | Add defer attribute | | Cache | Clear browser cache | | Domain mismatch | Verify domain config |
Consent Not Persisting
| Cause | Solution | |-------|----------| | Cookie blocked | Check SameSite settings | | Cookie domain | Verify domain config | | Privacy mode | Expected behavior |
Tags Firing Without Consent
| Cause | Solution | |-------|----------| | Missing default | Add gtag consent default | | Tag not configured | Enable consent checks | | Race condition | Increase wait_for_update |
Tags Not Firing After Consent
| Cause | Solution | |-------|----------| | Update not sent | Check CMP callback | | Wrong mapping | Verify category to signal map | | Trigger issue | Check GTM trigger config |
Regional Considerations
Geolocation-Based Consent
// Different defaults by region
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'region': ['EU', 'GB', 'EEA']
});
gtag('consent', 'default', {
'ad_storage': 'granted',
'analytics_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted',
'region': ['US']
});
CMP Geo-Targeting
Most CMPs support showing banners only in required regions:
- Cookiebot: Geographic targeting in settings
- OneTrust: Geolocation rules
- CookieYes: Region-based display
Previous: First-Party Data Strategy Next: Privacy Audit Guide