Cookie Consent Banner plugin Cookie Consent and how to use it with GTM
Change log
- 2022-08-07 : Fixed article and added an additional setting when using GTM.
- 2022-07-10 : Page published
Introduction
Consent Management Platforms (CMPs) are gaining attention as a tool to explain to users what data a website or application collects and how it is used, and to obtain their consent.
There are several free tools and paid cloud services, but this article introduces the free JavaScript plugin Cookie Consent
and how to implement it.
We will also introduce how to implement it for multilingual support and for using Google Analytics with Google Tag Manager.
What is Cookie Consent?
Cookie Consent
is a free, GDPR-compliant JavaScript plugin.
You can download it below.
orestbida/cookieconsent: Simple cross-browser cookie-consent plugin written in vanilla js
Outline for settings
The following is an outline of the procedure.
- load the plugin's JavaScript
- load the CSS for the plugin
- write the configuration code of the plugin
- edit the
<script>
tag of the analyzer or such tools you are using
Note if you are using Google Tag Manager
If you are using Google Tag Manager (GTM), you must fire Cookie Consent before the GTM loading code.
Load the plugin's JavaScript and CSS
Load CSS and JS as follows.
The location of the JS can be in the body
tag or in the head
tag.
<html>
<head>
<!-- head content -->
<!-- Deferred CSS loading (recommended) -->
<link rel="stylesheet" href="<path-to-cookieconsent.css>" media="print" onload="this.media='all'">
</head>
<body>
<!-- body content -->
<script defer src="<path-to-cookieconsent.js>"></script>
</body>
</html>
CSS and JS can also be loaded from CDN.
# CDN links
https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.8.2/dist/cookieconsent.js
https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.8.2/dist/cookieconsent.css
When using GTM, the order is as follows.
GTM's script
tag attributes are explained later in this article.
<!-- Plug-in JS -->
<script defer src="../../src/cookieconsent.js"></script>
<!-- Plugin Settings JS -->
<script defer src="cookieconsent-init.js"></script>
<!-- GTM Tag -->
<script type="text/plain" data-cookiecategory="analytics">
// Google Tag Manager (configured with GA internally)
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');
</script>
Write the configuration code for the plugin - basic writing
Next, prepare the configuration code for the plugin.
The following is the basic settings.
See the comments in the code for details.
// Obtaining the Cookie Consent Plugin
var cc = initCookieConsent();
// Run the plugin with your settings.
cc.run({
current_lang : 'en', // Language Preferences. Multilingual support is described later in this article.
autoclear_cookies : true, // Automatically delete cookies when cookies in a particular category are opted out. default: false
cookie_name: 'cc_cookie_demo1', // Cookie name for this plugin. default: 'cc_cookie'
cookie_expiration : 365, // Cookie expiration date for this plugin. default: 182
page_scripts: true, // If the plugin is set by an attribute value in the script tag as described in this article, set it to true. default: false
// auto_language: null, // Automatic language setup. Described later. default: null; could also be 'browser' or 'document'
// autorun: true, // default: true
// delay: 0, // default: 0
// force_consent: false,
// hide_from_bots: false, // default: false
// remove_cookie_tables: false // default: false
// cookie_domain: location.hostname, // default: current domain
// cookie_path: "/", // default: root
// cookie_same_site: "Lax",
// use_rfc_cookie: false, // default: false
// revision: 0, // default: 0
// Layout Settings. You can change the layout by changing the options here.
gui_options: {
consent_modal: {
layout: 'box', // box,cloud,bar
position: 'bottom right', // bottom,middle,top + left,right,center
transition: 'slide' // zoom,slide
},
settings_modal: {
layout: 'box', // box,bar
// position: 'left', // right,left (available only if bar layout selected)
transition: 'slide' // zoom,slide
}
},
// Code you want to run on first run
onFirstAction: function(){
console.log('onFirstAction fired');
},
// Code you want to run when the cookie is accepted
onAccept: function (cookie) {
console.log('onAccept fired ...');
},
// Code to be run when cookie consent content is changed
onChange: function (cookie, changed_preferences) {
console.log('onChange fired ...');
},
// Language-specific settings
languages: {
'en': {
// Modal text
consent_modal: {
title: ' We use cookies! ',
description: 'Hi, this website uses essential cookies to ensure its proper operation and tracking cookies to understand how you interact with it. The latter will be set only after consent. <button type="button" data-cc="c-settings" class="cc-link">Let me choose</button>',
primary_btn: {
text: 'Accept all',
role: 'accept_all' // 'accept_selected' or 'accept_all'
},
secondary_btn: {
text: 'Reject all',
role: 'accept_necessary' // 'settings' or 'accept_necessary'
}
},
// Detailed cookie settings explanation
settings_modal: {
title: `Cookie Settigs`,
save_settings_btn: 'Save settings',
accept_all_btn: 'Accept all',
reject_all_btn: 'Reject all',
close_btn_label: 'Close',
// Name of the entry in the table that describes each cookie
cookie_table_headers: [
{col1: 'Name'},
{col2: 'Domain'},
{col3: 'Expiration'},
{col4: 'Description'}
],
blocks: [
{
title: 'Cookie usage',
description: 'I use cookies to ensure the basic functionalities of the website and to enhance your online experience. You can choose for each category to opt-in/out whenever you want. For more details relative to cookies and other sensitive data, please read the full <a href="#" class="cc-link">privacy policy</a>.'
}, {
title: 'Strictly necessary cookies',
description: 'These cookies are essential for the proper functioning of my website. Without these cookies, the website would not work properly',
toggle: {
value: 'necessary', // Cookie category name. The category name defined here is specified in the data-cookiecategory attribute of the script tag.
enabled: true,
readonly: true // cookie categories with readonly=true are all treated as "necessary cookies"
}
}, {
title: 'Performance and Analytics cookies',
description: 'These cookies allow the website to remember the choices you have made in the past',
toggle: {
value: 'analytics', // Cookie category name. The category name defined here is specified in the data-cookiecategory attribute of the script tag.
enabled: false,
readonly: false
},
// Write text according to the names of the items in the table above.
// If you omit the cookie_table itself, you can also omit the description of each cookie.
cookie_table: [
{
col1: '^_ga',
col2: 'google.com',
col3: '2 years',
col4: 'description ...',
is_regex: true // Enable/disable regular expressions
},
{
col1: '_gid',
col2: 'google.com',
col3: '1 day',
col4: 'description ...',
}
]
}, {
title: 'Advertisement and Targeting cookies',
description: 'These cookies collect information about how you use the website, which pages you visited and which links you clicked on. All of the data is anonymized and cannot be used to identify you',
toggle: {
value: 'targeting', // Cookie category name. The category name defined here is specified in the data-cookiecategory attribute of the script tag.
enabled: false,
readonly: false
}
}, {
title: 'More information',
description: 'For any queries in relation to my policy on cookies and your choices, please <a class="cc-link" href="https://orestbida.com/contact">contact me</a>.',
}
]
}
}
}
});
Edit the <script>
tag of the analysis tool etc. you are using
Edit the attribute values of the tags of the 3rd party scripts used by the analysis tool, etc. according to the values of settings_modal > blocks > toggle > value
in the configuration code, like type="text/plain" data-cookiecategory="{category name}"
.
Please refer to the following sample.
<script type="text/plain" data-cookiecategory="analytics" src="analytics.js" defer></script>
<script type="text/plain" data-cookiecategory="ads">
console.log('"ads" category accepted');
</script>
The setup is now complete.
Settings for using Google Analytics with GTM
When using Google Analytics with GTM, select a tag type that suits your measurement method, such as Universal Analytics
or GA4
, instead of Custom HTML
on the GTM administration screen.
If you use Custom HTML
and enter analytics measurement tags, you will receive the following warning.
Any gtag commands in custom HTML may not work as intended due to how the data layer processes information.
This means that you cannot directly edit the attribute values of the script
tag.
In that case, a little tweak is needed.
First, you need to make sure that the GTM
is loaded after the Cookie Consent
, which is the same as the aforementioned code.
Then, put the attribute value for Cookie Consent
in the attribute value of the script
tag that loads the GTM.
<!-- Plug-in JS -->
<script defer src="../../src/cookieconsent.js"></script>
<!-- Plugin Settings JS -->
<script defer src="cookieconsent-init.js"></script>
<!-- GTM Tag -->
<script type="text/plain" data-cookiecategory="analytics">
// Google Tag Manager (configured with GA internally)
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');
</script>
Next, in the Cookie Consent
setting, write that data will be stored in the Google Analytics cookie if consent is obtained in the analytics
category.
onChange: function(cookie, changed_preferences) {
if (cc.allowedCategory('analytics')) {
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
} else {
gtag('consent', 'update', {
'analytics_storage': 'denied'
});
}
}
onChange
is a callback function that fires when the cookie consent setting is changed.
Please refer to the following
Available callbacks - orestbida/cookieconsent
For more information on allowedCategory
, click here.
API methods - orestbida/cookieconsent
analytics_storage
is one of the data that Google Tag Manager manages based on consent, and is one of the consent types to enable or disable cookies for analytics.
Another consent type that stores advertising-related cookies is ad_storage
.
For more information, please refer to this article.
Manage consent settings (web) | Tags | Google Developers
Consent configuration - Tag Manager Help
Added on 2022-08-07
The code in the onChange
callback function above did not set the cookie properly.
Therefore, I have solved this problem by adding the following code below the GTM measurement tag.
<!--- enable analytics when "analytics" category is selected --->
<script type="text/plain" data-cookiecategory="analytics">
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
</script>
Adding GTM Consent Mode features to Cookie Consent was mentioned in the following Issue, but currently, the above code is a recommended way to handle this issue.
(The thread also mentions the onChange method, but for some reason it didn't work in my environment)
Add native support of GTM's Consent Mode (GCM) · Issue #110 · orestbida/cookieconsent · GitHub
Trigger type for tags set in GTM
The trigger type for the tags managed by GTM should be "Page View" instead of "Initialization".
With "Initialization," the tags are not fired properly even if the user agrees to the use of cookies in the Cookie Consent banner.
Configure multiple languages
First, to configure multiple languages, prepare the following blocks for each language
languages: {
'en': {}
}
Next, set the language to be displayed according to the page you are accessing.
If you want to explicitly change the language, set current_lang
to the language you want to display.
If you want to change the language according to the environment, remove current_lang
and apply auto_language
.
There are two options for auto_language
.
auto_language: 'browser', // change according to your browser settings
auto_language: 'document', // change according to <html lang="...">
That is all for this article.