This article is for developers that maintain a consent management solution on websites that use Google Tag Manager (GTM).
This page introduces consent types in Google Tag Manager and shows you how to integrate them with your consent management solution.
Why use a tag template for consent?
When you provide a tag template, your users can integrate your consent solution in a codeless way, saving significant time and effort.
Users can set default consent states using a consent mode template 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.
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. |
ad_user_data |
Sets consent for sending user data to Google for online advertising purposes. |
ad_personalization |
Sets consent for personalized 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 |
Create a new consent template
Consent mode keeps track of visitor consent choices and tag consent checks ensure that tag behavior adjusts accordingly. When creating a new consent template, follow the best practices:
Use the Tag Manager consent mode APIs setDefaultConsentState and updateConsentState instead of
gtag consent
.Set default consent states immediately upon firing using the Consent Initialization - All Pages trigger.
The CMP has to prompt the visitor as soon as possible to grant or deny consent for all applicable consent types.
When a visitor indicates their consent choice, the CMP has to pass the updated consent state.
1. Create a new template
This implementation approach uses one field in the template to hold the default consent state. The implementation code reads that field to set the default consent state at runtime. For the update command, your code attempts 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.
To create a consent template:
- Log into your Google Tag Manager account.
- In the left navigation, select Templates.
- In the Tag Templates pane, click New.
To set default consent states:
- Select the Fields tab, click Add Field > 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. Learn more about setting up consent defaults for different regions. - 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)
Optional: To add support for ads data redaction:
- Click Add Field, choose Checkbox, and change the field name to
ads_data_redaction
. - Update the Display name to
Redact Ads Data
Learn more about cookie behavior with ads data redation
Optional: To add support for passing through URL parameters:
- Click Add Field, choose Checkbox, and change the field name to
url_passthrough
. - Update the Display name to
Pass through URL parameters
Learn more about passing through URL parameters
To add the implementation code:
- Open the Code tab in the template editor.
- In the code sample below, edit the placeholder fields.
- Copy the code and replace the boilerplate code in the template editor with it.
- Save the template.
// 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 = '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',
ad_user_data: consent['adUserDataConsentGranted'] ? 'granted' : 'denied',
ad_personalization: consent['adPersonalizationConsentGranted'] ? '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) => {
/*
* Optional settings using gtagSet
*/
gtagSet('ads_data_redaction', data.ads_data_redaction);
gtagSet('url_passthrough', data.url_passthrough);
gtagSet('developer_id.your_developer_id', true);
// Set default consent state(s)
data.defaultSettings.forEach(settings => {
const defaultData = parseCommandData(settings);
// wait_for_update (ms) allows for time to receive visitor choices from the CMP
defaultData.wait_for_update = 500;
setDefaultConsentState(defaultData);
});
// Check if cookie is set and has values that correspond 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();
Next, configure permissions for accessing consent state and for accessing cookies.
To add permissions 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, for
ad_user_data
,ad_personalization
, andanalytics_storage
. If you need additional consent types, add them in the same way. - Click Save.
To add permissions 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.
2. Create unit tests
See Tests for information on creating tests for your template.
3. 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);
});
};
Update the 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',
'ad_user_data': 'granted',
'ad_personalization': 'granted',
'analytics_storage': 'granted',
'functionality_storage': 'granted',
'personalization_storage': 'granted',
'security_storage': 'granted'
});
About 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
|
Additional metadata
You can use the gtagSet API to set following optional parameters:
These APIs are only available within the GTM template sandbox environment.
Pass through 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 won't 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, no new cookies are set for advertising
purposes. Additionally, third-party cookies previously set on google.com and
doubleclick.net won't 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.
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.
gtagSet('ads_data_redaction', true);
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.
You only need a developer ID when your implementation will be used across multiple websites by unrelated companies or entities. If the implementation will be used by one site or entity, don't apply for a developer ID.
gtagSet('developer_id.<your_developer_id>', true);
Provide documentation for your users
Your users will use your consent template to set up a tag that collects user consent. Provide documentation for your users that explains the following best practices:
- How to set consent defaults in the Settings table.
- How to set up consent defaults for different regions by adding additional table rows.
- Trigger the tag on the Consent Initialization - All Pages trigger.
Next steps
If you want to provide your template to all Tag Manager users, upload it to the Community Template Gallery.