klaro-js
klaro-js copied to clipboard
Help implementing Google Consent Mode
Hi,
We have implemented Google Consent Mode according to your documentation. We fire our GTM tags based on an event trigger like klaro-googleTagManager-accepted. It does fire the tag, however, the tag itself does not function properly. In the case of Google Analytics, we have no page views.
The klaro-google-analytics-accepted event fires fairly late. It fires after the page view has been generated, and also the dataLayer within the klaro-google-analytics-accepted event doesn't contain a pageView. So it does fire the tag, but it doesn't generate a pageView. I don't see my website activity in the real-time view of Google Analytics.
My full config file:
export default {
testing: window.klaroTesting,
default: false,
disablePoweredBy: true,
additionalClass: 'gdpr',
acceptAll: true,
hideDeclineAll: true,
noticeAsModal: true,
groupByPurpose: false,
styling: {
theme: ['light'],
},
translations: window.klaroTranslations,
services: [
{
name: 'sessionCookies',
purposes: ['functional'],
default: true,
required: true,
},
{
name: 'googleTagManager',
purposes: ['marketing'],
default: false,
onAccept: function(opts) {
window.gtmIsLoaded = true;
// we notify the tag manager about all services that were accepted. You can define
// a custom event in GTM to load the service if consent was given.
for (let k of Object.keys(opts.consents)) {
if (opts.consents[k]) {
dataLayer.push({'event': 'klaro-' + k + '-accepted'})
}
}
// if consent for Google Analytics was granted we enable analytics storage
if (opts.consents[opts.vars.googleAnalyticsName || 'google-analytics']) {
gtag('consent', 'update', {'analytics_storage': 'granted'});
}
// if consent for Google Ads was granted we enable ad storage
if (opts.consents[opts.vars.adStorageName || 'google-ads']) {
gtag('consent', 'update', {'ad_storage': 'granted'});
}
},
onInit: function(opts) {
window.dataLayer = window.dataLayer || [];
window.gtmIsLoaded = null;
window.gtag = function(){dataLayer.push(arguments)}
gtag('consent', 'default', {'ad_storage': 'denied', 'analytics_storage': 'denied'});
gtag('set', 'ads_data_redaction', true);
},
onDecline: function(opts) {
window.gtmIsLoaded = false;
window.gtag = function(){dataLayer.push(arguments)}
gtag('consent', 'default', {'ad_storage': 'denied', 'analytics_storage': 'denied'})
gtag('set', 'ads_data_redaction', true)
},
vars: {
googleAnalytics: 'google-analytics'
}
},
{
// In GTM, you should define a custom event trigger named `klaro-google-analytics-accepted`
// which should trigger the Google Analytics integration.
name: 'google-analytics',
purposes: ['marketing'],
cookies: [
/^_ga(_.*)?/ // we delete the Google Analytics cookies if the user declines its use
],
}
],
};
Any help would greatly be appreciated!
I stumbled upon the same problem when trying to implement this. I could not get the code to work, but I did not bother to find a fix because I did not like this approach anyways. It seemed way to complicated for such a simple problem: If users consent to a service, send an event to Google Tag Manager.
Using Google Tag Manager
Here is the implementation I settled with:
function announceConsent (consentGiven, service) {
const name = service.name
const consentGivenPart = consentGiven ? 'accepted' : 'rejected'
sendEvent(`consent.${consentGivenPart}.${name}`)
}
function sendEvent (name, data = {}) {
window.dataLayer.push({
'event': name,
...data,
})
}
window.klaroConfig = {
version: 1,
...
services: [
{
name: 'googleAnalytics',
title: 'Google Analytics',
purposes: ['analytics'],
cookies: [
/^_ga(_.*)?/
],
callback: announceConsent,
},
],
}
After that, you just need to add a trigger in Google Tag Manager that listens for the consent.googleAnalytics.accepted event and hook it up to the configuration for Google Analytics.
Using just Google Analytics without Google Tag Manager
I also want to mention that most of the time, you really do not need Google Tag Manager. You can just as easily hook up Google Analytics via Klaro directly:
window.klaroConfig = {
version: 1,
...
services: [
{
name: 'googleAnalytics',
title: 'Google Analytics',
purposes: ['analytics'],
cookies: [
/^_ga(_.*)?/
],
},
],
}
In your HTML, just do:
<script
type="text/plain"
data-type=""
data-name="googleAnalytics"
data-src="https://www.googletagmanager.com/gtag/js?id=<MEASUREMENT_ID>></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '<MEASUREMENT_ID>');
</script>
This approach of importing Google Analytics directly is documented here.
Still works in 2023 – thanks @fjahn
Attention: One thing has to be adjusted, if someone uses the Google Tag Manager implementation from @fjahn.
Either use consent.accepted.googleAnalytics (instead of consent.googleAnalytics.accepted) in Google Tag Manager or change the implementation of the announceConsent function so it produces the correct name:
- sendEvent(`consent.${consentGivenPart}.${name}`)
+ sendEvent(`consent.${name}.${consentGivenPart}`)
@fjahn Maybe you could edit your original Post?