If you maintain a consent management solution for sites that use Google Tag Manager (GTM), we strongly recommend creating a template to support Google Consent Mode. A Consent Mode template enables your users to adopt Consent Mode and to integrate it with their consent solution in a codeless way, saving significant time and effort.
Consent Mode templates support the creation of tags that set default consent state and communicate visitor consent choices to Google Tag Manager. This ensures optimal functioning of Google and third-party tags that support Consent Mode.
As a template creator, you can implement Consent Mode templates for internal use or publish them in the Community Template Gallery to make them publicly available. Consent Management Platform (CMP) providers who offer Consent Mode templates have the opportunity to be listed in our Consent Mode documentation and have the Template Gallery picker feature their templates.
This page introduces consent state and consent types and shows how to use them with Consent Mode APIs. The last section provides an example of how to use the APIs to create a Tag Manager template. If you are new to Consent Mode or to Tag Manager templates, the following articles provide background information:
Consent state and consent types
Google and third-party tags adjust their storage behavior based on a consent
state of either granted
or denied
. They can have built in consent checks
for any of the following consent types:
Consent Type | Description |
---|---|
ad_storage |
Enables storage, such as cookies, related to advertising |
analytics_storage |
Enables storage, such as cookies, related to analytics (for example, visit duration) |
functionality_storage |
Enables storage that supports the functionality of the website or app such as language settings |
personalization_storage |
Enables storage related to personalization such as video recommendations |
security_storage |
Enables storage related to security such as authentication functionality, fraud prevention, and other user protection |
The template should give your users the ability to set a default consent state for each consent type used by their website. They might also want to set default consent states for different regions.
GTM users should fire tags created with your template on all pages using the Consent Initialization trigger. This ensures that it will fire before any other tags. The template code should set the configured default consent states immediately upon firing. The CMP should then prompt the visitor as soon as possible to grant or deny consent for all applicable consent types. When a visitor indicates their choice, the CMP should pass in the updated consent state via the appropriate template API. Consent Mode keeps track of visitor consent choices and tag consent checks ensure that tag behavior adjusts accordingly.
Consent APIs
Consent Mode implementations on sites that leverage GTM for tagging should use
the GTM-specific APIs for managing consent states, setDefaultConsentState and
updateConsentState. They may optionally use the gtagSet API to set the
ads_data_redaction
and url_passthrough
settings as appropriate. These APIs
are only available within the GTM template sandbox environment.
The default consent state should be set as early as possible when the page
loads, using the Consent Initialization event to trigger the tag. Consent
updates should be signaled to GTM as soon as possible after the user provides
consent, or when the user's previous consent choice is loaded from cookies.
There are a number of possible approaches for triggering updateConsentState
.
The examples later in this article demonstrate two possible options.
Default consent state
To configure the default consent settings, use the setDefaultConsentState API.
The following example illustrates the use of the setDefaultConsentState
call.
It denies ad_storage
by default and grants consent to the other storage types.
It also uses wait_for_update
to allow time to receive visitor choices from the
CMP.
const setDefaultConsentState = require('setDefaultConsentState');
setDefaultConsentState({
'ad_storage': 'denied',
'analytics_storage': 'granted',
'functionality_storage': 'granted',
'personalization_storage': 'granted',
'security_storage': 'granted',
'wait_for_update': 500
});
Update consent state
After a website visitor has indicated their consent choices, typically through interacting with a consent banner, the template code should update consent states accordingly with the updateConsentState API.
The following example shows the updateConsentState
call for a visitor that
indicated they consent to all storage types. Again, this example uses hardcoded
values for granted
, but in practice, these should be determined at runtime
using the visitor’s consent that is collected by the CMP.
const updateConsentState = require('updateConsentState');
updateConsentState({
'ad_storage': 'granted',
'analytics_storage': 'granted',
'functionality_storage': 'granted',
'personalization_storage': 'granted',
'security_storage': 'granted'
});
Region-specific behavior
To set default consent states that apply to visitors from particular areas,
specify a region (according to ISO 3166-2) in the template. Using region values enables template users to
comply with regional regulations without losing information from visitors
outside those regions. When a region is not specified in a
setDefaultConsentState
command, the value applies to all other regions.
For example, the following sets default status for analytics_storage
to
denied
for visitors from Spain and Alaska, and sets analytics_storage
to
granted
for all others:
const setDefaultConsentState = require('setDefaultConsentState');
setDefaultConsentState({
'analytics_storage': 'denied',
'region': ['ES', 'US-AK']
});
setDefaultConsentState({
'analytics_storage': 'granted'
});
Most specific takes precedence
If two default consent commands occur on the same page with values for a region
and subregion, the one with a more specific region will take effect. For
example, if you have ad_storage
set to 'granted'
for the region US
and
ad_storage
set to 'denied'
for the region US-CA
, a visitor from California
will have the more specific US-CA
setting take effect.
Region | ad_storage |
Behavior |
---|---|---|
US | 'granted' |
Applies to users in the US that are not in CA |
US-CA | 'denied' |
Applies to users US-CA |
Unspecified | 'granted' |
Uses the default value of 'granted' . In this example, that applies to users who aren't in the US or US-CA
|
Passing ad click, client ID, and session ID information in URLs
When a visitor lands on an advertiser’s website after clicking an ad, information about the ad might be appended to the landing page URLs as a query parameter. To improve conversion accuracy, Google tags usually store this information in first-party cookies on the advertiser’s domain.
However, if ad_storage
is denied
, Google tags will not save this information
locally. To improve ad click measurement quality in this case, advertisers can
optionally pass ad click information through URL parameters across pages using a
feature called URL passthrough.
Similarly, if analytics_storage
is set to denied, URL passthrough can be used
to send event and session-based analytics (including conversions) without
cookies across pages.
The following conditions must be met to use URL passthrough:
- Consent-aware Google tags are present on the page.
- The site has opted in to using the URL passthrough feature.
- Consent Mode is implemented on the page.
- The outgoing link refers to the same domain as the current page's domain.
- A gclid/dclid is present in the URL (Google Ads and Floodlight tags only)
Your template should allow the template user to configure whether or not they would like to enable this setting. The following template code is used to set url_passthrough to true:
gtagSet('url_passthrough', true);
Redact ads data
When ad_storage
is denied, new cookies will not be set for advertising
purposes. Additionally, third-party cookies previously set on google.com and
doubleclick.net will not be used. Data sent to Google will still include the
full page URL, including any ad click information in the URL parameters.
To further redact your ads data when ad_storage
is denied, set ads_data_redaction
to true.
gtagSet('ads_data_redaction', true);
When ads_data_redaction
is true and ad_storage
is denied, ad click
identifiers sent in network requests by Google Ads and Floodlight tags will be
redacted.
Developer ID
If you are a CMP vendor with a Google-issued developer ID, use the following method to set this as early as possible in your template.
gtagSet('developer_id.<your_developer_id>', true);
Implementation example
This example shows how to create a template that reads cookies from the consent management solution to get visitor consent choices. This makes those choices available to GTM as early as possible during the loading process when a visitor made their selections on a previous page.
To follow this example, you will create one field in the template to hold the
default consent state. The implementation code will read that field to set the
default consent state at runtime. For the update command, your code will attempt
to read a cookie set by the consent solution to store visitor consent choices.
You will also set up a callback for updateConsentState
to handle the case
where a visitor has yet to make their consent selections or decides to change
their consent.
The main steps include:
- Use the Template Editor to create the template
- Integrate the template with the consent solution
- Template user setup
Use the Template Editor to create the template
- Log into your Google Tag Manager account.
- In the left navigation, select Templates.
- In the Tag Templates pane, click New.
Add Fields
- Select the Fields tab, click Add Field.
- Choose Param table.
- Change the name to
defaultSettings
. - Expand the field.
- Update the Display name to
Default settings
. - Click Add column, choose Text input, change the name to
region
and check the Require column values to be unique box. - Expand the column, and change the display name to
Region (leave blank to have consent apply to all regions)
. The statement in parenthesis is documentation for your template users. - Click Add column, choose Text input, change the name to
granted
. - Expand the column and change the display name to
Granted Consent Types(comma separated)
. - Click Add column, choose Text input, change the name to
denied
. - Expand the column and change the display name to
Denied Consent Types (comma separated)
. - Click Add Field, choose Checkbox, and change the field name to
ads_data_redaction
. - Update the Display name to
Redact Ads Data
.
Add Code
Copy the code below and replace parameters in brackets (the cookie name and check for updated consent state) with those appropriate for your implementation. Once updated, use your code to replace the boilerplate code in the GTM Code tab. Save the template after pasting.
// The first two lines are optional, use if you want to enable logging
const log = require('logToConsole');
log('data =', data);
const setDefaultConsentState = require('setDefaultConsentState');
const updateConsentState = require('updateConsentState');
const getCookieValues = require('getCookieValues');
const callInWindow = require('callInWindow');
const gtagSet = require('gtagSet');
const COOKIE_NAME = '<replace_with_your_cookie_name>';
/**
* Splits the input string using comma as a delimiter, returning an array of
* strings
*/
const splitInput = (input) => {
return input.split(',')
.map(entry => entry.trim())
.filter(entry => entry.length !== 0);
};
/**
* Processes a row of input from the default settings table, returning an object
* which can be passed as an argument to setDefaultConsentState
*/
const parseCommandData = (settings) => {
const regions = splitInput(settings['region']);
const granted = splitInput(settings['granted']);
const denied = splitInput(settings['denied']);
const commandData = {};
if (regions.length > 0) {
commandData.region = regions;
}
granted.forEach(entry => {
commandData[entry] = 'granted';
});
denied.forEach(entry => {
commandData[entry] = 'denied';
});
return commandData;
};
/**
* Called when consent changes. Assumes that consent object contains keys which
* directly correspond to Google consent types.
*/
const onUserConsent = (consent) => {
const consentModeStates = {
ad_storage: consent['adConsentGranted'] ? 'granted' : 'denied',
analytics_storage: consent['analyticsConsentGranted'] ? 'granted' :
'denied',
functionality_storage: consent['functionalityConsentGranted'] ? 'granted' :
'denied',
personalization_storage:
consent['personalizationConsentGranted'] ? 'granted' : 'denied',
security_storage: consent['securityConsentGranted'] ? 'granted' : 'denied',
};
updateConsentState(consentModeStates);
};
/**
* Executes the default command, sets the developer ID, and sets up the consent
* update callback
*/
const main = (data) => {
// Set developer ID
gtagSet('developer_id.<replace_with_your_developer_id>', true);
// Set default consent state(s)
data.defaultSettings.forEach(settings => {
const defaultData = parseCommandData(settings);
defaultData.wait_for_update = 500;
setDefaultConsentState(defaultData);
});
gtagSet('ads_data_redaction', data.ads_data_redaction);
// Check if cookie is set and has values that corresopnd to Google consent
// types. If it does, run onUserConsent().
const settings = getCookieValues(COOKIE_NAME);
if (typeof settings !== 'undefined') {
onUserConsent(settings);
}
/**
* Add event listener to trigger update when consent changes
*
* References an external method on the window object which accepts a
* function as an argument. If you do not have such a method, you will need
* to create one before continuing. This method should add the function
* that is passed as an argument as a callback for an event emitted when
* the user updates their consent. The callback should be called with an
* object containing fields that correspond to the five built-in Google
* consent types.
*/
callInWindow('addConsentListenerExample', onUserConsent);
};
main(data);
data.gtmOnSuccess();
Add Permissions
Next, configure permissions for accessing consent state and for accessing cookies.
For managing consent states:
- Select the Permissions tab and click Accesses consent state.
- Click Add consent type.
- Click the box and select
ad_storage
from the drop-down menu. - Check Write.
- Click Add
Repeat steps 2-5, substituting analytics_storage
for ad_storage
.
Finish by clicking Save.
For accessing cookies:
- Select the Permissions tab and click Reads cookie value(s).
- Under Specific, enter the names of each of the cookies your code needs to read to determine the user’s consent choices, one name per line.
- Click Save.
Tests
See Tests for information on creating tests for your template.
Integrate the template with the consent solution
The following code shows one example of how this template could be integrated with the code for your consent management solution by adding a listener:
// Array of callbacks to be executed when consent changes
const consentListeners = [];
/**
* Called from GTM template to set callback to be executed when user consent is provided.
* @param {function} Callback to execute on user consent
*/
window.addConsentListenerExample = (callback) => {
consentListeners.push(callback);
};
/**
* Called when user grants/denies consent.
* @param {Object} Object containing user consent settings.
*/
const onConsentChange = (consent) => {
consentListeners.forEach((callback) => {
callback(consent);
});
};
Template user setup
You should provide documentation for template users. They will use this template to set up a tag that uses the Consent Initialization - All Pages trigger. In the Settings table, they should enter a list of the consent types and whether they want to grant or deny each by default. If default settings should differ based on where the user is located, they should create one row for each set of regions that share the same default consent state.