How to set the Google Analytics cookie only after another consent cookie is set and "true"?

How to set the Google Analytics cookie only after another consent cookie is set and "true"?

问题

I am using React/Nextjs for my website and the react-cookie-consent library. It creates a pop up where the user can agree to the cookie policy. If agreed, a cookie is set: CookieConsent with value "true".

Additionally, I want to use Google Analytics to track users if they agree (click Accept on the popup).

But it doesnt work: The Google Analytic cookies _ga and G_ENABLED_IDPS are set before the user clicks on the pop up.

Funny thing is, I only realized that on the Microsoft Edge Browser. In Chrome, these cookies are not set before the user gives consent.

This is my current code in _document.js:

<Head>
          {/* Global Site Tag (gtag.js) - Google Analytics */}
          <script
            async
            src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
          />
          <script
            dangerouslySetInnerHTML={{
              __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}            
            gtag('js', new Date());
            
          `}}
          />
          
          <script type="text/javascript" src="/static/blockReactDevTools.js" />
          
          <link href="https://fonts.googleapis.com/css?family=Cabin&display=swap" rel="stylesheet" />

</Head>

I  played around using some hints from the internet, and came up with this version which also doesn't work:

<Head>
          {/* Global Site Tag (gtag.js) - Google Analytics */}
          <script 
            async
            src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
          />

          <script        
            dangerouslySetInnerHTML={{
                __html: `
              
              var gtagId = '${GA_TRACKING_ID}';

              window['ga-disable-' + gtagId] = true;

              window.dataLayer = window.dataLayer || [];

              function gtag(){dataLayer.push(arguments);}   

              gtag('js', new Date());

              function getCookie(cname) {
                var name = cname + "=";
                var ca = document.cookie.split(';');
                for(var i = 0; i < ca.length; i++) {
                  var c = ca[i];
                  while (c.charAt(0) == ' ') {
                    c = c.substring(1);
                  }
                  if (c.indexOf(name) == 0) {
                    return c.substring(name.length, c.length);
                  }
                }
                return "";
              }

              window.addEventListener("load", function() {
                var isCookieConsentTrue = getCookie("CookieConsent") == 'true';

                if(isCookieConsentTrue){
                    window['ga-disable-' + gtagId] = false;
                    alert("Cookie Consent given!");
                    
                  }  else {
                    alert("Cookie Consent NOT given!");
                    window['ga-disable-' + gtagId] = true;
                  }
              });          
            
            `}}
          />

          <script type="text/javascript" src="/static/blockReactDevTools.js" />

          
          <link href="https://fonts.googleapis.com/css?family=Cabin&display=swap" rel="stylesheet" />

</Head>

I don't know if this is a nextjs specific issue, or something plain stupid general.

Can anyone guide me to a working solution?

EDIT: I tried the "Universal Analytics" approach of the suggestion. Suggested Solution make my helper functions to log events and pageviews fail (see below). Do I need also the gtag manager?

 

回答1

The way you were doing it is Opt-out. The GA cookie is always set, as soon as the client requests the gtag.js. This however doesn't comply with GDPR. What you should look into is Opt-in, so that no GA cookie is set without consenting.

The general idea is to async load the gtag.js once the client has consented. For full functionality of gtag functions you have to load the gtag.js on every page-load if the client already consented. Best practice to do this is with a cookieconsent cookie set on consent. There's a widely used js library for this, which generates a popup and sets the consent-cookie for you.

Reference:
https://www.osano.com/cookieconsent/documentation/javascript-api/
You can generate code for the layout of your cookie banner by clicking Start Coding here: https://www.osano.com/cookieconsent/download/ https://github.com/osano/cookieconsent/blob/dev/examples/example-7-javascript-api.html

Following code has to be implemented on every page in the <head> section:

<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.1/cookieconsent.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.1/cookieconsent.min.js" data-cfasync="false"></script>
<script>
var popup;
window.addEventListener('load', function(){
  window.cookieconsent.initialise({
   //set revokeBtn if you don't want to see a tiny pullup bar overlapping your website
   //if revokeBtn is set, make sure to include a link to cookie settings in your footer
   //you can open your banner again with: popup.open();
   //revokeBtn: "<div class='cc-revoke'></div>",
   type: "opt-in",
   theme: "classic",
   palette: {
       popup: {
           background: "#000",
           text: "#fff"
        },
       button: {
           background: "#fd0",
           text: "#000"
        }
    },
    onInitialise: function(status) {
      // request gtag.js on page-load when the client already consented
      if(status == cookieconsent.status.allow) setCookies();
    },
    onStatusChange: function(status) {
      // resquest gtag cookies on a new consent
      if (this.hasConsented()) setCookies();
      else deleteCookies(this.options.cookie.name)
    },
/* enable this to hide the cookie banner outside GDPR regions
    law: {
      regionalLaw: false,
    },
    location: true,
    },
*/
    function (p) {
        popup = p;
  })
});

//it is absolutely crucial to define gtag in the global scope
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}', {'anonymize_ip': true});

function setCookies() {
    var s = document.createElement('script');
    s.type = "text/javascript"
    s.async = "true";
    s.src = "https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}";
    var x = document.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);

    // you can add facebook-pixel and other cookies here
};

function deleteCookies(cookieconsent_name) {
        var keep = [cookieconsent_name, "DYNSRV"];

        document.cookie.split(';').forEach(function(c) {
            c = c.split('=')[0].trim();
            if (!~keep.indexOf(c))
                document.cookie = c + '=;' + 'expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/';
        });
};
</script>

Note:
Make sure that the gtag.js is loaded on every page-load once the consent-cookie was set to allow. Use event_callback to see if a gtag event was sent. You can use the gtag function without checking for the consent-cookie. If gtag.js is not present it just adds elements to the window.dataLayer without any functionality. To avoid errors, the function gtag() has to be declared in global scope and before use.

// cookie-check is not necessary when gtag is in global scope
//if(popup.hasConsented()) { 
    gtag('event', 'sign_up', {
            'method': 'Google',
            'event_callback': function(){alert('event was sent');}
        });
//}

You don't have to send an extra pageview event, unless you want to manually specify the path. setCookies() already sends the current document path along with the config

 

回答2

Use gtag's consent config options. Currently, the following can be put before any data measurement commands (config or event) are run in the header:

gtag('consent', 'default', {
  'ad_storage': 'denied',
  'analytics_storage': 'denied'
});

Then run this once the user has approved or if a consent cookie is present:

gtag('consent', 'update', {
  'ad_storage': 'granted',
  'analytics_storage': 'granted'
});

If you use Facebook Pixel, it works in a similar way. E.g. fbq('consent', 'revoke'); then fbq('consent', 'grant').

 

Github搜索,两个repository用到相似的代码

主体代码应该是参考这个https://www.cnblogs.com/chucklu/p/16497448.html

 

https://github.com/lixiaomeng546/hongye/blob/7bc6d5ddcdca220c7a1976b3116504a8f130b2c6/game/game3.html

<!-- Google Analytics -->
<script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}

    gtag('set', 'developer_id.dNzMyY2', true); // OneTrust developer id
    gtag('consent', 'default', {
        'analytics_storage': 'denied',
        'ad_storage': 'denied',
        'wait_for_update': 1000
    });

    gtag('js', new Date());

    if (window.navigator.standalone) {
        gtag('set', {
          'dimension1': true
        });
    }

    gtag('config', "UA-23605814-1");

    if (!window._optanonCallbacks) {
        window._optanonCallbacks = [];
    }

    _optanonCallbacks.push(function () {
        // if consent given for cookies then
        // update gtag consent
        var analytics = (OnetrustActiveGroups.indexOf('C0002') != -1);
        var ads = (OnetrustActiveGroups.indexOf('C0004') != -1);
        if (analytics || ads) {
            gtag('consent', 'update', {
                'analytics_storage': analytics ? 'granted' : 'denied',
                'ad_storage': ads ? 'granted' : 'denied'
            });
        }
    });

</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-23605814-1"></script>
<!-- End Google Analytics -->

 

https://github.com/nightsky108/developcanvas.com/blob/01d52275bb7695745418a0e6dce195acbca6179a/templates/partials/analytics.tmpl.html

{{#if prod}}
<script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}

    gtag('set', 'developer_id.dNzMyY2', true); // OneTrust developer id
    gtag('consent', 'default', {
        'analytics_storage': 'denied',
        'ad_storage': 'denied',
        'wait_for_update': 1000
    });

    // Google Analytics
    gtag('js', new Date());

    gtag('config', 'UA-23605814-1');

    if (!window._optanonCallbacks) {
        window._optanonCallbacks = [];
    }

    _optanonCallbacks.push(function () {
        // if consent given for cookies then
        // update gtag consent
        var analytics = (OnetrustActiveGroups.indexOf('C0002') != -1);
        var ads = (OnetrustActiveGroups.indexOf('C0004') != -1);
        if (analytics || ads) {
            gtag('consent', 'update', {
                'analytics_storage': analytics ? 'granted' : 'denied',
                'ad_storage': ads ? 'granted' : 'denied'
            });
        }
    });
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-23605814-1"></script>
<script src="https://playcanvas.com/static/platform/js/onetrust/consent.js"></script>
{{/if}}

 

posted @ 2022-07-19 17:59  ChuckLu  阅读(199)  评论(0编辑  收藏  举报