Make the module compatible with Google Consent Mode

Created on 11 January 2023, almost 2 years ago
Updated 8 May 2023, over 1 year ago

Problem/Motivation

Hi. This module is not compatible with Google Consent mode which is suggested by Google to respect user choices without manually configuring Google Tag Manager with custom implementations.

Proposed resolution

  1. Use the provided patch to modify the module JS and make it compatible.
  2. Configure the module using appropriate settings (more on that later).

The patch simply changes how the data are pushed to GTM DataLayer. Instead of simply pushing an array of custom variables, those variables are pushed following the Google Consent mode model. More details can be found on the official documentation.

How to configure the module

Currently Google supports the following consent types:

  • ad_storage
  • analytics_storage
  • functionality_storage
  • personalization_storage
  • security_storage

This means that for each EU Cookie Compliance category we should send the appropriate type.

Example: if we've added the "Advertisement" category on EU Cookie Compliance module, on the GTM data configuration we'll have to put the following JSON code:

{
    "ad_storage": "@status"
}

Let me know what do you think about. Thank you.

โœจ Feature request
Status

Needs work

Version

2.0

Component

Code

Created by

๐Ÿ‡ฎ๐Ÿ‡นItaly finex

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • ๐Ÿ‡ท๐Ÿ‡ดRomania reszli Tรขrgu Mureศ™

    this is related to โœจ Improve dataLayer events Fixed

    I'm wondering if this is still relevant after those improvements

    if so, could you please create an MR against 2.x

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly finex

    Yes, the request is still relevant because with this patch you don't have to manually read the dataLayer on GTM but you simply have to enable the consent mode to allow all compatible products to work as intended.

    Probably I will redo a new patch in the near future.

  • ๐Ÿ‡ช๐Ÿ‡ธSpain Carlitus

    Have you been able to make progress on this?

    My company might be interested in sponsoring this functionality and we could also create a step by step manual to implement adding tags to the GTM with the consent mode.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom gebiss

    I have applied the patch and it seems the solution works.

    I did the following:
    1. Added the patch to the eu_cookie_compliance_gtm
    2. Added GTM data to each consent category via the eu_cookie_compliance module in the following format:

    For the Necessary cookies
    {
    "functionality_storage": "@status"
    }

    For the Preferences cookies
    {
    "personalization_storage": "@status"
    }

    For the Statistics cookies
    {
    "analytics_storage": "@status"
    }

    For the Marketing cookies
    {
    "ad_storage": "@status"
    }

    3. On GTM > Admin > Container Settings enabled the Consent overview (BETA). More info at https://www.youtube.com/watch?v=MqAEbshMv84&t=2s
    Now the GTM displays consent (built in or additional) information on each tag used.

    Now, when I deselect the Statistics cookies on the EU Cookie bar the GA4 doesn't show visits in the Real-time. This makes me think the solution works.

    Thanks!

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly finex

    @Carlitus: I've plan to work on this task on September, if you want to contribute please contact me.

    @Gebiss: did you successfully applied the patch to the 2.x branch?

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom gebiss

    @FiNeX No, I couldn't apply the patch initially - The source code was different but I found the source code that matched the one in the patch. It's here - https://git.drupalcode.org/issue/eu_cookie_compliance_gtm-3357677. I copied the eu_cookie_compliance_hooks.js to my module files (I use version 2.0.2) and then applied the patch.

  • ๐Ÿ‡ช๐Ÿ‡ธSpain Carlitus

    @FiNeX where can i reach you? Here https://www.realizzazione-siti-vicenza.com/?

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly finex

    @Carlitus: Drupal.org personal contact is fine. Thank you.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands roaldnel

    I have created an updated patch the applies the changes to the 2.x code base. Similar to post #5 by gebiss, Google Consent Mode v2 tags can also be added as their own categories or I simply added them under the marketing category as a collection which applies the access as expected based on the selection made by the user for "Marketing" cookies:

    {
    "ad_personalization": "@status",
    "ad_storage": "@status",
    "ad_user_data": "@status"
    }

  • Status changed to Needs review 11 months ago
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands bram.velthoven
  • Status changed to RTBC 11 months ago
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium tijsdeboeck Antwerp ๐Ÿ‡ง๐Ÿ‡ช ๐Ÿ‡ช๐Ÿ‡บ ๐ŸŒŽ

    We've tested this patch on a couple of our websites, and it works perfectly, in combination with google_tag 2.0.3.
    We haven't had any issues with our D10.2.x sites, nor on the D9.5.x sites that haven't been upgraded.

  • ๐Ÿ‡ฆ๐Ÿ‡นAustria agoradesign

    I really hate the whole topic of configuring GTM, especially the consent mode stuff. It should be easy, it looks easy, sometimes it just works, sometimes it's a pita. I never have a good feeling on configuring that. I'm never 100% sure, whether it works like expected.

    I (and for sure many many many other people here) would love to see an in-depth guide on how to correctly configure the whole stack - from the Drupal side with google_tag, eu_cookie_compliance and eu_cookie_compliance_gtm, to the GTM side, including GA4, Ads and let's say Facebook Pixel - including steps that other tutorials are often missing, like which triggers to use, etc

    eg I stumbled yesterday and today to refactor an older, but small GTM account. The debugger showed me updates of consent states, but in the end, it didn't really matter, whether the storages were denied, because all the tags just kept on firing. I have finally solved it by loading the community template from https://www.simoahava.com/custom-templates/consent-mode/ and also had to build me custom variables, which I then based on the first-party cookie of eu_cookie_compliance, which shouldn't be necessary at all...

    So, if anyone has a easy to use recipe for dummies and writes a blog post about this, I'm sure it'll get a lot of views :)

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands Summit

    Hi, +1 for easy recipe for dummies!
    Thanks in advance,
    greetings,

  • ๐Ÿ‡ฌ๐Ÿ‡ทGreece Stamatis Giannakis

    Is anyone else experiencing a new session ID on every page load, even after accepting all cookie categories?
    The problem disappears when switching the consent method to "Opt-out. Track visitors by default, unless they choose to opt out."

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium bramvandenbulcke

    @Statamis Giannakis. I've seen this as well in the past.

    Can you uncheck the checkbox "Enable cookie(s) automatic-removal when consent isn't given" (Under Cookie handling) in the settings of EU Cookie Compliance and test again?

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium bramvandenbulcke

    We have a minor issue in our install.

    We did the following:

    And for the cookies:

    Functional cookies:

    {
    "functionality_storage": "@status",
    }

    Analytical cookies:

    {
    "analytics_storage": "@status"
    }

    Marketing cookies:

    {
    "ad_personalization": "@status",
    "ad_storage": "@status",
    "ad_user_data": "@status",
    }

    There is one weird thing. We receive an additional event cookie_consent_post_pref_load. This shouldn't be here I guess. Any ideas? See the screenshot.

  • ๐Ÿ‡ฌ๐Ÿ‡ทGreece Stamatis Giannakis

    @bramvandenbulcke, thanks for your response, it was very helpful. I'm also receiving this additional consent state in GTM Debugger. Additionally, I noticed that all events sent from the GTM module are sent prior to consent and are they are denied. I believe the module should update the user consent state at the consent initialization trigger, not after. Also, to avoid the warning "A tag read consent state before a default was set," I need to trigger the Google Tag Manager tag at DOM Ready.

  • Does this also work with the "Opt-in" consent method, or only "Opt-in with categories"?

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands Summit

    Hi, we tried this solution. But it didn't work some how. When we use this combined with google ads...the referrer is not staying correct, and therefor the counting fot google analytics is not working correct anymore. Any one else same kind of outcome?
    greetings,

  • First commit to issue fork.
  • Merge request !8Resolve #3332626 consent mode โ†’ (Open) created by heddn
  • heddn Nicaragua

    Closed ๐Ÿ› Make the module compatible with Google Consent Mode - sending Default as well as Update Consent Closed: duplicate as duplicate and move over some of its fixes into the MR.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany sleitner

    Patchfile of the last MR

  • heddn Nicaragua

    heddn โ†’ changed the visibility of the branch 3332626-consent_mode to hidden.

  • heddn Nicaragua

    heddn โ†’ changed the visibility of the branch 3332626-consent_mode to hidden.

  • heddn Nicaragua

    heddn โ†’ changed the visibility of the branch 3332626-consent_mode to active.

  • ๐Ÿ‡ต๐Ÿ‡ฑPoland kewin.nammert

    Referring to the google documentation . The consent default event should execute before the gtm implementation script hence the problem with the consent not being set on the consent initialization trigger. To avoid that you can delay all tags trigger on consent_update which is not ideal. It's better to adjust the patch.

  • heddn Nicaragua

    This module has an explicit dependency on google_tag.module. And, even more explicitly, this issue adds a dependency on the google_tag/gtag library. That module already handles the default event. Doing it in this module would be duplicative.

  • ๐Ÿ‡ต๐Ÿ‡ฑPoland kewin.nammert

    I understand. In that case, is there any way to solve the problem of sending e.g. ecommerce events from google_tag module after consents load. I see a similar problem in #18. gtag('consent', 'default'... is probably set too late no? I wonder if there is a way to set consents before gtm.init.

  • ๐Ÿ‡ต๐Ÿ‡ฑPoland kewin.nammert

    For anyone who is struggling with the above problem. For me events sometimes were sent without consent info. In the gtm configuration, just create a trigger group (per tag sending data to GA4) containing cookie_consent_update trigger and desired trigger for the tag.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands Summit

    Hi Kewin,

    Do you may be have your case as example here, how to do this? Thanks!

    greetings,

  • ๐Ÿ‡ต๐Ÿ‡ฑPoland kewin.nammert

    Hi the case was more complex than I thought. As you can see in comment #18 the add_to_cart event was triggered before consent which lead sometimes to some problems for my client.

    I ended up with configuring GA4 tag for cookie_consent_update trigger. For commerce events I've created a patch that moves events in dataLayer array after all consent is set.

  • ๐Ÿ‡จ๐Ÿ‡ญSwitzerland zilloww

    Hello, I tried the last patch but had an issue because it sets the default consent but it doesn't really make sense because `drupal/google_tag` module already does it and it's required.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom scott_euser

    Thanks everyone for the work on this!

    The latest patches seem very different than the merge request. Can we please all contribute to the merge request or open a separate branch in the merge request if you feel the approach should be drastically different? If the patches can be discarded and we go back to the MR perhaps the patches can be hidden to avoid confusion. We should update the issue summary to be clear as well.

    Unfortunately this is not ready for the maintainers to review if its unclear what to review.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium matthiasm11
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium matthiasm11

    eu_cookie_compliance.js states the following statuses:

    Statuses:
     null: not yet agreed (or withdrawn), show popup
     0: Disagreed
     1: Agreed, show thank you banner
     2: Agreed
    

    The merge request in this ticket only supports status 2 (agreed), but we need to support both 1 (agreed, show thank you banner) and 2 (agreed).

    The default consent is handled by the google_tag module, see โœจ Additional consent mode options Active .

    I tried to add a commit to the merge request, but got the "Members who can merge are allowed to add commits." error.
    I've created a new patch which supports status 1 and 2, the changes of the merge request and the changes of patch #34.

  • Status changed to Needs review about 1 month ago
  • ๐Ÿ‡จ๐Ÿ‡ญSwitzerland berdir Switzerland

    > I tried to add a commit to the merge request, but got the "Members who can merge are allowed to add commits." error.

    There's a button next to the merge rquest info to get commit access.

    > Does this also work with the "Opt-in" consent method, or only "Opt-in with categories"?

    This module currently only integrates with categories.

    After testing and trying to integrate this into the non-category mode, I reduced this small non-configurable snippet:

          if (typeof gtag !== 'function') {
            return;
          }
    
          const setConsent = function (consentStatus) {
            gtag('consent', 'update', {
              'analytics_storage': consentStatus
            });
          }
    
          if (Drupal.eu_cookie_compliance.hasAgreed()) {
            setConsent('granted');
          }
    
          Drupal.eu_cookie_compliance('postStatusSave', function(response) {
            setConsent((response.currentStatus == 1 || response.currentStatus == 2) ? 'granted' : 'denied');
          });
        }
    

    You can put this in a custom module javascript file in a behavior, as usual, depend on google_tag/gtag and eu_cookie_compliance/eu_cookie_compliance. It's not sufficient when using categories, but maybe you can adjust that for your use case then. I'm still not sure which types are actually required for which use case, we don't have ads, so I really only care about analytics.

    Based on my testing, this module currently triggers way too many consent updates and events. If I understand this correctly then a single call to gtag() with the update argument already triggers the cookie_consent_update event, it doesn't need to be done again. Also the load event from eu_cookie_compliance seems problematic, I saw multiple triggers of that on the same page, so I went instead with a non-handler hasAgreed() check, then I also only need to send an update and the even if the user actually agreed.

    The patch is also going to break this for anyone using this module with custom data because it only supports the consent mode flags now and will set everything in that scope.

    And last, instead of redefining the gtag function, which seems strange, I simply added a check to make sure it's defined.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom scott_euser

    Thanks @berdir for the details. So it seems there are two issues then with the current MR correct?

    1. Without categories does not work
    2. With categories does work but sends too many events

    Beyond that we also do not really use adwords so hopefully someone following this issue can also test that out.

    With categories does work but sends too many events
    For this bit, perhaps we can update this bit in the current MR then:

    gtag('consent', 'update', data);
    

    To conditionally only call it if its different from the original? E.g. when we loop through the categories here:

        for (let category in details) {
          if ('third_party_settings' in details[category]) {
            for (let prop in details[category].third_party_settings.eu_cookie_compliance_gtm.gtm_data) {
    

    We could have some sort of flag that checks if there is a change from the original state, and have something like

    if (hasChanges) {
      gtag('consent', 'update', data);
    }
    
  • ๐Ÿ‡จ๐Ÿ‡ญSwitzerland berdir Switzerland

    > Without categories does not work

    This isn't a limitation of this issue, but of the module. There is currently simply no way to configure it for the no-categories mode, as that's the only thing it hooks into.

    In that case, because implement your own script, there is another, possibly even easier mode. That is to use the eu_cookie_compliance settings to completely disable google_tag scripts before consent is given:

    modules/contrib/google_tag/js/gtag.js||google_tag/gtag
    modules/contrib/google_tag/js/gtm.js||google_tag/gtm
    modules/contrib/google_tag/js/gtag.ajax.js||google_tag/gtag.ajax
    

    If you only use google tag manager for analytics, that might be OK, for other cases it might be too strict. But with the enforced consent V2 basic mode, the result is kinda the same.

Production build 0.71.5 2024