Help implementing Google Consent Mode
modelesque opened this issue · comments
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?