Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add native support of GTM's Consent Mode (GCM) #110

Open
jelen07 opened this issue Nov 21, 2021 · 24 comments
Open

Add native support of GTM's Consent Mode (GCM) #110

jelen07 opened this issue Nov 21, 2021 · 24 comments
Labels
💬 discussion enhancement New feature or request help wanted Extra attention is needed

Comments

@jelen07
Copy link

jelen07 commented Nov 21, 2021

Feature request

Add native support of Consent Mode for GTM like CookieHub, etc.

Snímek obrazovky 2021-11-21 v 8 45 10

Screenshot from CookieHub's administration that affect their plugin behaviour, which in case of this widget could be done by configuration.

Proposed solution

Add new configuration key ie. gtm_consent_mode: true|false (default) which will be automaticaly sending consents to the GTM.
It's Google native support of what does the data-cookiecategory do. It could be used together.

Usefull links

  1. https://support.cookiehub.com/article/79-google-consent-mode-gcm
  2. https://support.cookiehub.com/article/136-consent-mode-in-google-tag-manager
  3. https://developers.google.com/tag-platform/tag-manager/templates/consent-apis

Snímek obrazovky 2021-11-21 v 8 44 05

Screenshot from GTM tag's setting.
@orestbida orestbida added the enhancement New feature or request label Nov 22, 2021
@orestbida
Copy link
Owner

I've considered myself adding gtm internally before, since many use it. The only issue is that the plugin doesn't come with predefined categories and I can't know if the "analytics" (can be also translated in other languages) category is enabled or not.

This feature is something which could be implemented in a future v3 (I foresee plenty of breaking changes)

@jelen07
Copy link
Author

jelen07 commented Nov 23, 2021

Do have some example of integration with GCM? I'm trying to bind plugins onAccept and onChange functions with GCM but without success yet.

@orestbida
Copy link
Owner

orestbida commented Nov 23, 2021

This is probably the easiest way:

 <script>
   // Define dataLayer and the gtag function.
   window.dataLayer = window.dataLayer || [];
   function gtag(){dataLayer.push(arguments);}

   // Default ad_storage to 'denied'.
   gtag('consent', 'default', {
     'ad_storage': 'denied',
     'analytics_storage': 'denied'
   });
 </script>

 <!-- Google Tag Manager -->
 <script>(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-XXXXXX');</script>
 <!-- End Google Tag Manager -->

<!--- enable analytics when "analytics" category is selected --->
<script type="text/plain" data-cookiecategory="analytics">
    gtag('consent', 'update', {
        'analytics_storage': 'granted'
    });
</script>

<!--- enable ads when "ads" category is selected --->
<script type="text/plain" data-cookiecategory="ads">
    gtag('consent', 'update', {
        'ad_storage': 'granted'
    });
</script>

If you really need to enable gtag inside onAccept or onChange then something like this should work:

// ...
onAccept: function(){
    if(cc.allowedCategory('analytics')){
        gtag('consent', 'update', {
            'analytics_storage': 'granted'
        });
    }
    
    if(cc.allowedCategory('ads')){
        gtag('consent', 'update', {
            'ad_storage': 'granted'
        });
    }
}
// ...

you'd repeat the same code inside the onChange method. GTM code found here.

@jelen07
Copy link
Author

jelen07 commented Nov 24, 2021

Well, and what setup you're using in GTM - native consent mode or some other solution? What trigger is used?

GCM

@orestbida
Copy link
Owner

Mhm, I'm using Google Tag Manager configured with Google Analytics: GA4. ad_storage and analytics_storage should already be handled automatically without further configuration.

screen

(I updated the snippet above 'cause I had mixed the GTM code GTM-XXXXXXX with gtag.js snippet.)

@coli21
Copy link

coli21 commented Dec 3, 2021

@jelen07 @orestbida Did it work for you? Everything works fine with analytics but my Facebook Pixel does not load. "ad_storage" is set as condition in "Consent Settings" in GTM.

@orestbida
Copy link
Owner

@coli21 ,

hmm, I can't personally test facebook pixel's script, but I have tried with microsoft clarity — which also must be configured using the "custom html" option inside google tag manager — and it works properly.

Can you make sure that the "firing trigger" is set on "all pages"? Also, are you perhaps using "facebook pixel's consent mode" ?

@orestbida
Copy link
Owner

@coli21 ,

if you can't make it work, here's another way to fire facebook pixel's script, and that is by creating your own custom event and trigger!

To create a custom trigger: tag manager -> workspace -> triggers -> new -> trigger configuration -> choose trigger type -> choose "custom event" -> specify event name, e.g. "start_pixel" -> trigger fires on -> all custom events and save the trigger.

Now head over to facebook pixel's tag: Consent Settings (BETA) -> Require additional consent for tag to fire -> specify the custom event name, e.g. "start_pixel". On the trigger section below select only the newly created trigger.

Make sure to submit/publish changes!

The last piece of the puzzle is to manually send the custom event to google tag manager using dataLayer.push() like so:

<!--- enable ads when "ads" category is selected --->
<script type="text/plain" data-cookiecategory="ads">
    
    gtag('consent', 'update', {
        'ad_storage': 'granted'
    });

    // also enable facebook pixel
    dataLayer.push({'event': 'start_pixel'});
</script>

@coli21
Copy link

coli21 commented Dec 6, 2021

@orestbida Thanks for your answers.
This is my FB Pixel configuration inside Tag Manager. The code on the front end is the same one you used. This way does not word: when ads are accepted, the only cookie set is _gcl_au, but no FB pixel. What am I missing?

I'd like a "native" solution inside tag manager, without creating my own events or triggers.

Pixel GTM Configuration

@orestbida
Copy link
Owner

orestbida commented Dec 6, 2021

@coli21 ,

My bad! You don't NECESSARILY need to create a custom event.

You DO need the custom trigger, and the reason for that - based on my guess - is that unlike google's scripts which are well integrated with their own tools, third party scripts are not (yet)!

As I see it, It should be gtm's job to enable the custom scripts but it does not do that currently - perhaps it has to do with the "beta" flag next to "Consent Settings".

If facebook pixel's script only needs ad_storage consent to run, then you need to trigger the event manually using the dataLayer.push() method!

You need a custom trigger (active listener which will enable the script whenever it receives the custom event ad_storage)
dss

This applies to all third party scripts configured with the custom html option inside google tag manager.

<!--- enable ads when "ads" category is selected --->
<script type="text/plain" data-cookiecategory="ads">
    
    gtag('consent', 'update', {
        'ad_storage': 'granted'
    });

    // send manual event to enable all third party scripts — configured with gtm — which rely on `ad_storage` consent
    dataLayer.push({'event': 'ad_storage'});
</script>

The last option would be to configure facebook pixel using a community template
ddsds

Here's a more detailed tutorial regarding the "community template" configuration: How To Set Up The Facebook Pixel With Google Tag Manager

@coli21
Copy link

coli21 commented Dec 6, 2021

@orestbida Thank you, now I got it. In fact, now that I think about it, my Analytics code works fine with analytics_storage. I hope there will be a better integration for third-party scripts in the future.

In the meantime, I found another solution: I removed "ad_storage" from Pixel Configuration and I inserted the script as plain text. This way, the ad_storage activation on the frontend is no longer needed.

FB Pixel new Configuration

@jelen07
Copy link
Author

jelen07 commented Dec 7, 2021

@coli21 Check out the "Additional Consent Check" part. They (CookieHub) triggering cookiehub_consent_update event from their script amog with consent update.

Snímek obrazovky 2021-12-07 v 7 23 18

But how you can use custom trigger with other triggers? 😳
Snímek obrazovky 2021-12-07 v 7 25 38

@orestbida
Copy link
Owner

@jelen07,

a step-by-step guide:

custom-trigger-example.mp4

@jelen07
Copy link
Author

jelen07 commented Dec 10, 2021

@orestbida Yeah, that's pretty straightforward. But we're are trying to implement cookie consent only within the GTM - without additional implementation on the target websites. We will manage more than 500+ websites so additional changes in implementation will be highly time-consuming, which we would like to avoid.
Because of this, we've made a wrapper https://github.com/68publishers/cookie-consent, which basically consists of two parts - the wrapper itself and the GTM template.
It gives us a space to add some extra functionalities - default translations, default settings, and so on. All that stuff must be possibly overridden from GTM. We've done some pretty progress. But atm the setup requires extra triggers.
If some "GTM pro user" have any hint, how to fire tags right after the user gives consent without custom triggers, just with "native GTM's consents", it would be great 😅

@orestbida
Copy link
Owner

@jelen07

I don't see how this can be achieved without any work on the google tag manager side. It would be great if gtm extended its "native" behaviour to custom scripts too, but that does not work; perhaps things will change when the beta label goes away.

Currently, the only solution to this — as far as I know of — would be to create a community template for google tag manager.

The template would then be able to read events sent from dataLayer.push() and enable scripts accordingly (scripts have to be configured with the template/plugin's custom events).

@orestbida orestbida added help wanted Extra attention is needed 💬 discussion labels Dec 10, 2021
@orestbida orestbida pinned this issue Dec 10, 2021
@zdenekhatak
Copy link

zdenekhatak commented Dec 16, 2021

@jelen07 @orestbida

How about using https://www.simoahava.com/analytics/consent-settings-google-tag-manager/#listen-for-changes-in-consent-state listeners for consent changes?

Creating a bunch of gtm templates for various tags may do the trick and keep the logic separated.

@Mangatt
Copy link

Mangatt commented Dec 19, 2021

@orestbida
Your proposed solution looks nice, but I'm not sure how well it works after user opens settings again and deny previously granted consent. Do you think that this is enough or is it necessary to use callbacks?

It might be worth (and not that hard imo) to enable something like this:

<script type="text/plain" data-cookiecategory-deny="analytics">gtag("consent","update",{"analytics_storage":"denied"});</script>

What do you think?

@nungr
Copy link

nungr commented Jan 2, 2022

If someone opens settings and denies consent – cookies are deleted, but GTM sends cookies again on page reload. Quick solution for "analytics" ( cookieconsent-init.js):

onChange: function (cookie, changed_preferences) {   
        var len = changed_preferences.length;
        for (var i = 0; i < len; i++) {
            let name = changed_preferences[i];
            if (cookie.level.includes(name)) {
                if (name == "analytics") {
                    gtag('consent', 'update', {
                        'analytics_storage': 'granted'
                    });
                }
            } else {
                if (name == "analytics") {
                    gtag('consent', 'update', {
                        'analytics_storage': 'denied'
                    });
                }
            }
        }
    },

@AlkoKod
Copy link

AlkoKod commented Jan 13, 2022

For Facebook pixel use Facebook consent mode: fbq('consent', 'revoke'); and fbq('consent', 'grant;

Just edit your pixel's code in GTM to have consent setting before init:

<script>
  !function(f,b,e,v,n,t,s)
  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
  n.callMethod.apply(n,arguments):n.queue.push(arguments)};
  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
  n.queue=[];t=b.createElement(e);t.async=!0;
  t.src=v;s=b.getElementsByTagName(e)[0];
  s.parentNode.insertBefore(t,s)}(window, document,'script',
  'https://connect.facebook.net/en_US/fbevents.js');
  fbq('consent', 'revoke');
  fbq('init', 'PIXEL_ID');
  fbq('track', 'PageView');
</script>

And then call it on accept and on change functions like this:

onAccept: function (cookie) {
                    if (cc.allowedCategory('analytics')) {
                        gtag('consent', 'update', {
                            'analytics_storage': 'granted'
                        });
						fbq('consent', 'grant');
                    }},

The _fbp cookie is still there after revoking the consent, but it seems the pixel script is not running. So best solution for me yet.

@antonijo01
Copy link

antonijo01 commented Sep 17, 2023

I found step by step instructions how to implement Orestibda V2.9. with google consent mode:
https://uninterrupted.tech/blog/manage-user-cookie-consent-with-google-tag-manager-a-step-by-step-guide/
What would be the simplest way to implement something similar for version 3.0?
Is there a step by step tutorial somewhere?

@JoshuaCrewe
Copy link

@antonijo01 that has been one of the most useful articles I have ever read. Thank you so much for sharing!

@reklamasieciowa
Copy link

Hi, your plugin looks very nice. Before I came across it, I wrote my own one, but for WordPress.

I thought for a long time how to combine it with GTM, because without it there is no full Consent Mode. IMO Template for GTM works best.

I adapted the example given in the Google documentation to read consents from my cookie. You can easily and quickly adapt it to the structure of your cookie. Thanks to this, implementation in GTM is trivial: import the script template into GTM, add default settings (or change them), set the trigger to consent init, done.

My plugin also sends the consent update event, but adding it in your script takes a few minutes (onFirstConsent + onChange).

Would you like to talk about the possibility of implementing such a solution?

You probably know, there is time until March 2024 to implement Consent Mode V2 (two additional categories of consent).

@everyx
Copy link

everyx commented Apr 3, 2024

A GTM template for reference: https://github.com/68publishers/cookie-consent

@alxndr-w
Copy link

alxndr-w commented Jun 6, 2024

Hi, I'm a little bit late to the party and NOT using GTM. But as I develop a Consent Management plugin for REDAXO CMS using cookieconsent + iframemanager, I do want to support GCM v2.

So basically, if I'm correct, there are three important things that need to be solved:

  1. The ability to organize 3rd-party scripts and/or groups in the GCM given categories security_storage, ad_storage, analytics_storage, ...
  2. The ability to not only to track consent but to revoke it, as well as
  3. The ability to sync revoke with cookieconsent and GCM v2's which keeps this information seperate from cookieconsent in their predefined localStorage object.

Native support by cookieconsent should be possible if there's an attribute/property per service, which categories are affected (1.), an additional callback event, e.g. onRevoke() instead of only onChange() (2.) or an internal method of cookieconsent that already does the job (3.) based on the information stored per service in (1.).

Or is there something I'm missing? E.g. why there is a solution by @everyx with a complex template for GTM? Why should I integrate cookieconsent into GTM if I could integrate GCM into the configuration of cookieconsent?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💬 discussion enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests