Google-Analytics-Tracking-Cookie Opt-IN

Cookie-Opt-IN Google Analytics

Hmmm… Analytics-Kekse (Alle verwendeten Logos und Markenzeichen sind Eigentum ihrer eingetragenen Besitzer)

In diesem Artikel beschreibe ich, wie man das Javascript Cookie Consent by Osana (vormals Insites) dazu nutzen kann, um Google-Analytics erst nach expliziter Zustimmung zu laden. Der Text baut auf meinem vorherigen Artikel zum MATOMO-Tracking-Cookie Opt-IN auf und ich werde an eingen Stellen auf diesen verweisen.

1. Vorbereitungen

1.1 Tracking-ID aus Google Analytics heraus suchen

Damit wir Analytics sagen können, für welche Site Besuche aufgezeichnet werden sollen, brauchen wir die Tracking-ID. Diese findet man nach dem Login in Google Analytics unter Verwaltung (Zahnrädchen-Symbol unten links) → Property-Einstellungen im Format UA-XXXXXXXX-X.

1.2 Cookie Consent by Osana einbinden

Nun muss das Javascript sowie das Stylesheet für das Layout des Cookie-Banners in die eigene Site eingebunden werden (cookieconsent.min.js & cookieconsent.min.css). Wie man dabei am besten vorgeht, ohne sich ein neues Datenschutzproblem einzutreten, habe ich im Artikel MATOMO-Tracking-Cookie Opt-IN unter Punkt 1.2 notiert.

2. Der JS-Code für den Opt-In

In der Javascript-Datei eures Webprojektes, nennen wir sie hier mal beispielhaft main.js, wird Folgendes ergänzt (getestet mit der zum Zeitpunkt dieses Artikels aktuellen Version des Cookie Consent by Osano):

/**
* Functions for Google Analytics Opt-IN
* with Osano Cookie Consent (https://www.osano.com/cookieconsent/download/)
* v2.1 – 30.01.2021
* vektorkneter.de
* 
* 
* Changelog:
* v2.1 – 30.01.2021
* – some changes in clearCookie() wich might improve the reliability of 
* cookie clearing in Google Chrome (based on a single issue report)
* 
* v2.0 – 16.01.2021
* – added support for new tracking IDs with format G-XXXXXXXXXX
*/

// Google Analytics tracking ID
// You may use the old format UA-XXXXXXXX-X or the newer one G-XXXXXXXXXX
var $tracking_id = "UA-XXXXXXXX-X";

// OPTIONAL (set if you have trouble deleting cookies):
// Set Google Analytics Cookie domain & path (needed for clearing cookies – have look in the inspector to get the values needed)
// If set to false, values from window.location.hostname and window.location.pathname will be used
var $tracking_cookie_domain = false; // eg. ".example.com"
var $tracking_cookie_path = false;   // eg. "/"


// Insites Cookie Consent with Opt-IN for MATOMO tracking Cookie
// Source: https://cookieconsent.insites.com/documentation/disabling-cookies/
window.addEventListener("load", function () {
    window.cookieconsent.initialise({
        "palette": {
            "popup": {
                "background": "#000"
            },
            "button": {
                "background": "#72c326",
                "text":"#fff"
            }
        },
        "cookie": { 
            "expiryDays": 1 
         },
        "type": "opt-in",
        "content": {
            "message": "Wir verwenden Tracking-Cookies, um unsere Website stetig zu verbessern sowie für anonymisierte Nutzungsstatistiken.",
            "allow": "Einverstanden",
            "deny": "Ablehnen",
            "link": "Mehr erfahren",
            "href": "/datenschutz",
            "policy": 'Cookie Einstellungen'
        },
        onPopupOpen: function () {
            document.body.classList.add("cookieconsent-banner-opened");
        },
        onPopupClose: function () {
            document.body.classList.remove("cookieconsent-banner-opened");
        },
        onInitialise: function (status) {
            var type = this.options.type;
            var didConsent = this.hasConsented();
            if (type == 'opt-in' && didConsent) {
                // enable cookies
                embedTrackingCode();
            }
            if (type == 'opt-out' && !didConsent) {
                // disable cookies
                deleteGACookies();
            }
            if (type == 'opt-in' && !didConsent) {
                // disable cookies
                deleteGACookies();
            }
        },
        onStatusChange: function (status, chosenBefore) {
            var type = this.options.type;
            var didConsent = this.hasConsented();
            if (type == 'opt-in' && didConsent) {
                // enable cookies
                embedTrackingCode();
            }
            if (type == 'opt-in' && !didConsent) {
                // disable cookies
                deleteGACookies();
                location.reload();
            }
            if (type == 'opt-out' && !didConsent) {
                // disable cookies
                deleteGACookies();
                location.reload();
            }
        },
        onRevokeChoice: function () {
            var type = this.options.type;
            if (type == 'opt-in') {
                // disable cookies
                
            }
            if (type == 'opt-out') {
                // enable cookies
                embedTrackingCode();
            }
        },

    })
});


/* ---- NO FUTHER SETTINGS NEEDED BELOW THIS LINE ---- */

function embedTrackingCode(){
    // add <script> to head
    var gascript = document.createElement("script");
    gascript.async = true;
    gascript.src = "https://www.googletagmanager.com/gtag/js?id="+$tracking_id;
    document.getElementsByTagName("head")[0].appendChild(gascript, document.getElementsByTagName("head")[0]); 

    // track pageview
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', $tracking_id, { 'anonymize_ip': true }); 
    
    //console.log('Google Analytics Tracking enabled')
}


function deleteGACookies(){ 
    // build cookie name from $tracking_id
    // taking into account legacy format (UA-XXXXXXXX-X) and newer format (G-XXXXXXXXXX)
    var $gtag_cookie;
    if ($tracking_id.substring(0, 2) == "G-") {
        // new format: Remove "G-", prefix with "_ga_"
        //console.log('new tracking id');
        $gtag_cookie = "_ga_"+$tracking_id.replace(/G-/g, "");
    } else if ($tracking_id.substring(0, 3) == "UA-") {
        // old format: Replace "-" with "_", prefix "_gat_gtag_"
        //console.log('legacy tracking id');
        $gtag_cookie = "_gat_gtag_"+$tracking_id.replace(/-/g, "_");
    } else {
        // none of the booth formats detected
        console.warn('No valid tracking ID (UA-XXXXXXXX-X or G-XXXXXXXXXX) detected. Cookie deletion will not work!')
    }
    
    // clear cookies
    clearCookie('_ga',$tracking_cookie_domain,$tracking_cookie_path);
    clearCookie('_gid',$tracking_cookie_domain,$tracking_cookie_path);
    clearCookie('_gat',$tracking_cookie_domain,$tracking_cookie_path);
    clearCookie($gtag_cookie,$tracking_cookie_domain,$tracking_cookie_path);

    //console.log('Google Analytics Tracking disabled')
}




// function for deleting Cookies (such as that ones from Google Analytics)
function clearCookie(name,domain,path){
    if(!domain || domain==""){
        domain = "." + window.location.hostname;
    }
    if(!path || path==""){
        path = "/";
    }
    document.cookie = name + '=; domain=' + domain +'; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=' + path;
} 


// function for triggering a click on the cc-revoke button
// wich will show the consent banner again.
// You may use it in a link, such as this example:
// <a href="#" onclick="openCCbanner(); return false;">Cookie Consent</a>
function openCCbanner(){
    var el = document.querySelector('.cc-revoke');
    el.click();
}


// ---- OPTIONAL -------------------
// Google Analytics Opt-Out Cookie
var $tracking_disable_cookie = 'ga-disable-' + $tracking_id;
if (document.cookie.indexOf($tracking_disable_cookie + '=true') > -1) {
window[$tracking_disable_cookie] = true;
}
function gaOptout() {
    document.cookie = $tracking_disable_cookie + '=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
    window[$tracking_disable_cookie] = true;
    alert("Der Opt-Out-Cookie für das Deaktivieren von Google Analytics wurde abgelegt.")
}


/*
    PLACE THIS ON YOUR PRIVACY PAGE:
    
	<div style="background-color:#fdeac0; padding: 1em; margin: 1em 0;"><strong>Sie können die Erfassung durch Google Analytics verhindern, indem Sie auf folgenden Link klicken. Es wird ein Opt-Out-Cookie gesetzt, das die zukünftige Erfassung Ihrer Daten beim Besuch dieser Website verhindert: <br>
<a href="javascript:gaOptout()">Google Analytics deaktivieren</a></strong></div>
*/

2.1 Erläuterungen

In Zeile 10 definieren wir die Tracking-ID, welche bei Punkt 1.1 (siehe oben) heraus gesucht wurde. Das Skript akzeptiert dabei sowohl das ältere Format in der Form „UA-XXXXXXXX-X“ als auch das neuere „G-XXXXXXXXXX“.

In Zeile 15-16 kann die Cookie-Domain definiert werden (wichtig für das spätere Löschen der Cookies) und der Cookie-Pfad. Die Standard-Einstellung „false“ sollte in den meisten Fällen funktionieren – dann legt das Skript die Werte selbst fest. Hier muss also nur etwas eingetragen werden, falls das Löschen der Cookies nicht korrekt funktioniert.
Die Cookie-Domain ist dabei der Hostname eurer Website, im Beispiel .example.com – wobei der Punkt am Anfang sicherstellt, dass auch  www.example.com eingeschlossen wird. Sofern sich die Website nicht in einem Unterordner befindet, ist der Cookie-Path für gewöhnlich einfach ein Slash (/).

In den Zeilen 102-116 wird die Funktion deklariert, die beim Akzeptieren von Cookies aufgerufen wird. Dort wird in Zeile 113 Google-Analytics so konfiguriert, dass die IP-Adresse anonymisiert wird – das ist wichtig für den datenschutzkonformen Einsatz des Tracking-Tools.

Das console.log('Google Analytics Tracking enabled') in Zeile 115 sollte im Live-Betrieb natürlich auskommentiert oder gelöscht werden, hilft aber beim initialen Einrichten und Testen.

In Zeile 119–143 wird die Funktion deklariert, die aufgrufen wird wenn der Nutzer seine Zustimmung zurückzieht. Diese löscht – mithilfe eine weiteren Funktion – alle von Google Analytics gesetzten Cookies.

Das console.log('Google Analytics Tracking disabled) in Zeile 142 kann natürlich auch weg, wenn alles läuft.

In Zeile 19–97 steht der eigentliche Code des Cookie Consent Skriptes von Osano. Dort können die Farben und Texte angepasst werden und auch die Lebensdauer des Cookie-Consent-Cookies festgelegt werden (kürzer ist besser!). Außerdem wird in Zeile 41 die URL zur Datenschutzerklärung festgelegt – im Beispiel /datenschutz. Weitere Informationen zur Konfiguration des Cookie-Banners findet ihr in der offiziellen Dokumentation.

3. Testen

Das wars auch schon – nun sollte beim Aufruf einer Seite der Website das Banner am unteren Rand erscheinen und zwei Schaltflächen das Akzeptieren und Ablehnen des Trackings ermöglichen.

Um zu prüfen, ob auch tatsächlich nur der Request an MATOMO rausgeht (und der Cookie gesetzt wird) nachdem der Nutzer zugestimmt hat, bietet es sich an die Developer-Tools des Browsers zu nutzen. Wie das geht, habe ich drüben im Artikel MATOMO-Tracking-Cookie Opt-IN unter Punkt 3 beschrieben.

4. Bonus

4.1 Cookie-Banner per Link an beliebiger Stelle erneut öffnen

Nach dem Akzeptieren oder Ablehnen im Cookie Consent Banner zeigt die Lösung von Osano unten links ein kleines Slideout (fährt beim Mouseover aus), welches nach dem Anklicken das Banner erneut anzeigt und der Nutzer so eine Auswahl ändern kann. Wenn man das Banner aber auch über einen zusätzlichen Link erneut öffnen lassen möchte (z.B. in der Datenschutzerklärung oder über einen Link im Footer, neben Impressum, Datenschutz und den den ganzen Kram) dann kann man dafür folgende Link-Syntax nutzen:

<a href="" onclick="openCCbanner(); return false;">Cookie-Einstellungen</a>

Mehr dazu ebenfalls drüben im Artikel MATOMO-Tracking-Cookie Opt-IN unter Punkt 4.1.

4.2 Verdecken der Fußzeile mit Links zu Impressum & Datenschutzerklärung verhindern

Wie der javascript-affine Leser vielleicht bemerkt hat, macht der oben dargestellte JS-Code auch noch etwas Anderes: Er fügt bei geöffnetem (sichtbarem) Cookie-Banner dem body-Element die CSS-Klasse cookieconsent-banner-opened hinzu und entfernt diese auch wieder wenn das Banner ausgeblendet wird. Diese Klasse kann z.B. genutzt werden, um der Fußzeile der Website bei geöffnetem Cookie-Banner deutlich mehr padding-bottom zu geben, um somit das Verdecken wichtiger Links zu verhindern:

.cookieconsent-banner-opened footer{
 padding-bottom: 8em;
}

4.3 Opt-Out-Cookie setzen

In den Zeilen 176–180 des oben gezeigten Codes gibt es noch eine Funktion namens gaOptout(), welche zum Setzen eines Opt-OUT-Cookies genutzt werden kann. Im Prinzip ist das durch den Opt-IN nicht mehr nötig aber ich habe es trotzdem mal im Code-Snippet belassen – wer will kann diese Funktion z.B. innerhalb von deleteGACookies() nutzen, um beim Ablehnen von Cookies auch zusätzlich noch den Opt-Out-Cookie zu setzen. Oder man kann in z.B. in der Datenschutzerklärung Folgendes zum Auslösen dieser Funktion ins HTML einfügen:

<div style="background-color:#fdeac0; padding: 1em; margin: 1em 0;"><strong>Sie können die Erfassung durch Google Analytics verhindern, indem Sie auf folgenden Link klicken. Es wird ein Opt-Out-Cookie gesetzt, das die zukünftige Erfassung Ihrer Daten beim Besuch dieser Website verhindert: <br>
<a href="" onclick="gaOptout(); return false;">Google Analytics deaktivieren</a></strong></div>

Mögliche Verbesserungen

Das Code-Fragement enthält aktuell noch ungenutzte IF-Zweige, welche ich aber absichtlich drin gelassen habe, damit Jeder das nach Bedarf anpassen kann. Außerdem kann Version 4.0 des Cookie Consents von Osano auch anders initialisiert werden. Das oben abgebildete Code-Fragement hatte ich für Version 3.x geschrieben, es funktioniert aber auch tadellos mit Version 4.0 (und vermutlich allen 4.x-Versionen).

Gibt’s das auch für MATOMO Webanalyse?

Klar: MATOMO-Tracking-Cookie Opt-IN

Update am 15.01.2021: Funktioniert nicht mit neu angelegten Tracking-Properties

Erik schrieb in den Kommentaren, dass bei ihm der Tracking-Cookies nicht korrekt gelöscht wird. Er nannte mir auch die Adresse seines Projekts und ich dabe dort gesehen, dass sich die Syntax des Cookie-Namens inzwischen geändert hat. Das betrifft vermutlich nur neu eingerichtete Tracking-Properties, welche auch eine andere Tracking-ID haben (G-XXXXXXXXXX statt UA-XXXXXXXX-X), was allerdings zu prüfen ist. Das Tracking selber wird zwar weiterhin erst nach dem Opt-IN aktiviert – da erst dann der Tracking-Code von Google nachgeladen wird – aber ein einmal gesetzter Analytics-Cookie wird nicht korrekt gelöscht. Demzufolge rate ich aktuell von der Nutzung dieser Lösung ab.

Update am 18.01.2021: Funktioniert jetzt auch mit den neueren Tracking-IDs im Format G-XXXXXXXXXX

Nachdem Erik in den Kommentaren meldete, dass das Skript nicht mit den neuen Tracking-IDs funktioniert, habe ich den Code angepasst und im Artikel geändert. Die Lösung funktioniert nun also auch mit den neuen IDs. Danke an Erik für das Testen!

Update am 30.01.2021: Änderung in der Funktion clearCookie()

Tassilo wies in den Kommentaren darauf hin, dass die Funktion bei ihm das Cookie zwar leert aber der Browser den Cookie nicht entfernt. Ich selber konnte dieses Verhalten nicht reproduzieren, habe seinen Anmerkungen aber dennoch zum Anlass genommen, kleinere Anpassungen vorzunehmen. Kann ja nicht schaden.
Falls ihr den vorherigen Code bereits im Einsatz habt und dieser (wie in meinen Einsatzfällen) problemlos funktioniert, ist die Übernahme meiner heutigen Änderung nicht notwendig. Nur falls ihr auch wie Tassilo Probleme habt, sollte ihr euch die Änderung in Zeile 165 anschauen.

Das Skript ist nach besten Wissen getestet und erfüllt in meinem Szenario die gewünschten Anforderungen. Dennoch erfolgt die Nutzung des auf eigene Gefahr!

32 Kommentare Schreibe einen Kommentar

  1. Hallo. Danke für das Tutorial, sehr hilfreich.
    Mir ist jedoch eines aufgefallen:

    Nachdem ich auf Einverstanden klicke, laden die Cookies, was auch so sein soll. Wenn ich jetzt jedoch auf Ablehnen klicke, bleiben die Cookies leider weiterhin. Ich sehe dass auf eurer Website so ein ähnlicher Banner verwendet wird, dort ist das Problem jedoch nicht vorhanden. Nachdem man bei euch auf Einverstanden klickt und in Folge dessen auf Ablehnen, werden die Cookies wie verlangt entfernt wieder entfernt.

    Habe einiges probiert um das Problem mit eurem bereits erstelltem Skript zu lösen, nur leider war ich erfolglos. Könntet ihr mal sehen ob vielleicht etwas am Skript aktualisiert werden muss? Sind immerhin ein paar Monate vergangen seitdem der Beitrag erstellt wurde. :)

    Danke nochmals,
    LG

    • Hallo,

      vielen Dank für das Lob!
      Was das geschilderte Problem angeht: Damit die Cookies sauber gelöscht bzw. inaktiviert werden, ist es wichtig dass $tracking_cookie_domain und $tracking_cookie_path im Script angepasst werden. Außerdem ist es im Falle von Google so, dass die Cookies nicht direkt gelöscht sondern nur geleert und mit einem zurückliegenden Ablaufdatum versehen werden. Im Firefox werden derart inaktivierte Cookies nicht mehr angezeigt – Chrome hingegen zeigt sie weiterhin an (allerdings leer und mit geänderten Ablaufdatum).

      Hier auf diesem Blog nutze ich Matomo – dort gibt es im Gegensatz zu Google Analytics eine Methode zum Löschen der Cookies. Im obigen Snippet für Google Analytics wird hingegen clearCookie() von tcs.de genutzt. In Kombination mit dem Nicht-mehr-laden des Google Analytics Javascript sind diese inaktivierten, leeren Cookies aber aus meiner Nicht-Juristen-Sicht datenschutztechnisch i.O..

      Beste Grüße
      André

      • Danke für diesen tollen Code!
        Nur verstehe ich nicht, warum Du clearCookie() als Routine nutzt. Das leert nur den Wert, löscht aber nicht das Cookie, wie Du ja beschrieben hast.
        Folgendes hingegen löscht z.B. das _ga Cookie (auch in Chrome):

        document.cookie = ‚_ga‘ + ‚=; Path=/; Domain=.example.com; Expires=Thu, 01 Jan 1970 00:00:01 GMT;‘;

        Ich glaube bei clearCookie() wird die Zeit nicht richtig in die Vergangenheit gesetzt.
        LG Tassilo

        • Hallo Tassilo,

          vielen Dank für Dein Feedback!
          Eigentlich sollte es keinen Unterschied machen, ob das Verfallsdatum des Cookies wie in Deinem Beispiel auf den ersten Januar 1970 oder wie in meinem Beispiel auf den 31. Dezember 2000 gesetzt wird: Wichtig ist nur, dass das Datum in der Vergangenheit liegt.

          Technisch gesehen ist es korrekt, dass das Skript den Cookie nicht löscht – denn das kann JavaScript garnicht. Aber durch das Setzen des Verfallsdatum auf einen Zeitpunkt in der Vergangenheit, wird der Browser dazu verlasst den Cookie wegzuwerfen.

          Hast Du in Deinem Einsatzszenario Probleme dahingehend – wird der Cookie bei Dir nicht korrekt gelöscht?

          Beste Grüße
          André

          • Ja, durch clearCookie() wurde nur der Wert geleert, das Cookie blieb jedoch erhalten (Google Chrome).
            Daher nutze ich nun obigen Code mit document.cookie, um auf 1970 Expiry zu setzen, sodass Chrome die Cookies dann gar nicht mehr anzeigt.

          • P.S.: Der Unterschied zwischen beiden Codes ist:
            1) ‚=true;‘ in clearCookie vs. ‚=;‘ [leer] in meinem Code
            2) Dein Datum ist inkonsistent mit dem Wochentag, 31 Dec 2000 war kein Donnerstag. Evt. prüft das Chrome?

          • Hi Tassilo,

            vielen Dank für Deinen Kommentar!
            Es ist verwunderlich, dass das bei Dir nicht funktioniert denn ich habe den Code natürlich auch im Chrome getestet (welcher aktuell mein primärer Browser ist) und habe diesen auch auf Sites im Einsatz. Ohne Probleme.
            Die Inkonsistenz beim Datum (dass der Wochentag nicht stimmt) ist mir auch schon aufgefallen aber da es dennoch funktionierte habe ich das nicht geändert.

            Aber: Kann ja nicht schaden dass noch mal anzupassen – auch die von Dir genannte Änderung mit einem leeren Wert (statt „true“). Obwohl der Wert eigentlich keinen Unterschied macht, da der Browser abgelaufene Cookies unabhängig von deren Werten entfernt.

            Ich werde die vorgeschlagenen Änderungen also mal die Tage testen und dann den Code in diesem Artikel ändern.

            Beste Grüße
            André

  2. Hey,

    danke für dein Tutorial.

    ich denke die Fragen wird auch für andere Interessant sein, deswegen Frage ich einfach direkt mal hier. Wie kann ich dein Script denn erweitern das sowohl GA als auch MATOMO darin enthalten sind? Kann ich auch noch weitere Anbieter einfügen? Vielen Dank!

    • Hallo,

      für den (vermutlich oder hoffentlich recht seltenen) Fall, dass man MATOMO und Google Analytics gleichzeitig nutzen möchte, könnte man den Funktionen zum Aktivieren und Deaktivieren der Tracker eindeutige Namen geben und diese dann beim Erfüllen der entsprechenden Bedingungen jeweils beide aufrufen. In meinen Beispielen für MATOMOMATOMO und Google AnalyticsGoogle Analytics heißt die Funktion zum Aktivieren jeweils embedTrackingCode(), während die Funktionen zum Deaktivieren bereits unterschiedliche Namen haben (deleteMatomoCookies() bzw. deleteGACookies()) – da müsste man also zumindest die Aktivierungsfunktion embedTrackingCode() sinnvoll umbenennen (z.B. embedMatomoTracking() und embedGaTracking()).

      Bei weiteren Anbietern würde man ebenso vorgehen, wobei jeder Anbieter seine eigenen Methoden hat die man herausfinden und in passende Funktion zum Aktivieren und Deaktivieren packen muss.

      Aber letzlich hoffe ich, dass niemand auf die Idee kommt Nutzer unnötigerweise mit mehreren Anbietern zu Tracken.

  3. Hallo,

    erstmal danke für das tolle TuT.

    Ich habe alles so gemacht wie beschrieben (eigentlich :-D ), aber ich bekomme folgenden Fehler beim Aufruf der Seite:
    Uncaught TypeError: Cannot read property ‚initialise‘ of undefined
    at main.js:44
    Ich habe die main.js eingebunden im head:

    Es wird beim laden der Seite auch kein Cookie-Hinweis geöffnet, sicher an dem Fehler…

    Zeile 44:
    window.addEventListener(„load“, function () {
    window.cookieconsent.initialise({
    „palette“: {
    „popup“: {
    „background“: „#000“
    },
    „button“: {
    „background“: „#72c326“,
    „text“:“#fff“
    }
    },

    • Hallo Erik,

      die Fehlermeldung Cannot read property ‚initialise‘ of undefined
      at main.js:44
      deutet darauf hin, dass das Cookieconsent-Skript von Osano (siehe Schritt 1.2) nicht oder erst nach dem Aufruf der window.cookieconsent.initialise geladen wird. Also zum Zeitpunkt des window.cookieconsent.initialise-Aufrufs cookieconsent noch nicht bereitsteht.

      Prüfe mal bitte, ob das Consent-Skript von Osano korrekt geladen wird UND der Aufruf von window.cookieconsent.initialise erst danach erfolgt.

      Beste Grüße
      André

      • Hallo Andrè,

        habe gerade geschrieben, was ich gemacht habe, dabei ist mir aufgefallen, dass ich vergessen hatte die .css und die min.js einzubinden…

        PEINLICH! :-D

        aber danke für die Hilfe, hast du einen PayPal Spende Button?

        MfG
        Erik

          • Hallo André,

            könntest du kurz überprüfen, ob bei mir alles richtig gemacht wurde, über die Browser Entwicklertools? Ich sehe zwar, das die Cookies ablaufen, aber ein Cookie bleibt… ist es dann richtig so? Im Analytics Konto sehe ich schon Zugriffe… sogar aus Polen… Ich habe die Website mal in den infos mit angegeben… Habe halt etwas Respekt davor…

            MfG

            Erik

          • Hallo Erik,

            stimmt: Bei Dir wird der GA-Cookie nicht gelöscht.
            Das liegt wohl daran, dass der Cookie-Name jetzt eine andere Syntax besitzt als wie es zum Zeitpunkt meines Artikels der Fall war.
            Probiere bitte mal die Zeile var $gtag_cookie = "_gat_gtag_"+$tracking_id.replace(/-/g, "_"); durch Folgendes zu ersetzen: var $gtag_cookie='_ga_ZQXXXXXXX', wobei _ga_ZQXXXXXXX der Name des Cookie ist, den Du in den Entwicklertools siehst.

            Beste Grüße
            André

          • Hallo André,

            danke für deine Zeit die du dir nimmst…

            Hab es wie beschrieben angepasst:
            // var $gtag_cookie = „_gat_gtag_“+$tracking_id.replace(/-/g, „_“);
            var $gtag_cookie=’_ga_ZQ30LHC41H‘;

            der Cooki bleibt, wird auch nicht auf ungültig gesetzt oder geleert… Kann es noch wo anders hängen, dass die delete funkction nicht aufgerufen wird bei Ablehnung?

            Danke,

            Erik

          • Hallo Erik,

            ich schreibe Dir mal eine E-Mail – ist vielleicht besser als das hier in den Kommentaren zu klären ;-)
            Wir finden da schon eine Lösung und dann aktualisiere ich den Artikel.

            Beste Grüße
            André

  4. Das ist eine der gaaanz wenigen Websites, deren Qualität mit dem Inhalt ihrer Blogbeiträge übereinstimmt. Andere bloggen über die Notwenigkeit einer schnellen Website, während die eigene keinen Hering vom Tisch zieht, preisen Plugins an, deren Menü sie nie bedienten, klären über rechtl. Cookie-Banner Pflicht auf, aber den eigenen G-Tag als Session-Cookie eingebunden.

    Gerne will ich, den hier angebotenen Code nutzen, habe aber einige Fragen dazu. Kommt der in den header? Mein Script beginnt mit <meta name="google-site-verification" content="MfFM2v_6tFuQPzgqoLqhwKFMuRSKqArQeYZGOdAzulY"? Noch nutze ich UA-, kann G-XXXX mit rein oder vorher löschen?
    Vielen Dank dafür.

    • Hallo Banner bannt Cookie,

      vielen Dank für Dein Feedback und das damit verbundenen Lob!

      Zu Deinen Fragen:
      Das Skript gehört – wie die meisten Javascripte – aus Performance-Gründen in den Footer der Seite. Irgendwo vor dem schließenden . Javascript wirkt ja rendering-blockierend und sollte daher nach Möglichkeit erst zum Schluß geladen werden.

      Der von Dir genannte Ausschnitt aus dem Header (google-site-verification) hat allerdings nichts mit Google Analytics zu tun, zumindest nicht funktionell und ist datenschutztechnisch auch unproblematisch. Das ist ja nur die Verifizierung dass die Site Dir gehört – für gewöhnlich nötig im Rahmen der Einreichung in der Google Search Console.

      Wenn Du noch eine Tracking-ID mit „UA-“ am Anfang benutzt, so kannst Du diesen weiter verwenden. Ein Umstellung auf die neuere Version mit („G-“ am Anfang) ist nicht nötig. Wenn Du auf Probleme stößt, gib gern noch mal Bescheid.

      Beste Grüße
      André

  5. Hi!

    Tolles Tutorial, hat mir auch hinsichtlich code quality in JS weitergeholfen!

    Eine Sache sehe ich noch kritisch: Die G-XXXXXX… Properties gehören zu Google Analytics Property 4, richtig?
    (Sidenote: Universal Analytics wird dieses Jahr abgeschaltet, https://support.google.com/analytics/answer/11583528?hl=de)

    In diesem Fall:
    – Das ‚anonymize_ip‘ ist nicht mehr notwendig, da es automatisch enthalten ist.
    – Es gibt einen Einwillingungsmodus mit dem man Analytics beschneiden kann, sodass keine Cookies abgelegt werden – allerdings pingt das tag weiter, um eine Modellerierung / Hochrechnung auf Basis dieser Pings durchzuführen.
    Google empfiehlt natürlich das Tag mit denied consents einzubinden und dann bei opt-in den consent zu updaten. Revoken kann man das pingen nicht.

    Ich würde gerne deinen Weg gehen, suche aber nach einer Möglichkeit das Tag wieder zu entfernen, um das Tag zu entfernen. Ideen sind willkommen. Ich denke das Opt-Out Cookie reicht nicht.

    Die wichtigsten Informationen zum Einwilligungsmodus: https://support.google.com/analytics/answer/9976101

    Codesnippet als Beispiel für restricted default bei Einbindung und update nach opt-in:

    //Einwillingungsmodus default strict (denied, pingt aber)
    gtag(‚consent‘, ‚default‘, {
    ‚ad_storage‘: ‚denied‘,
    ‚ads_data_redaction‘: ‚true‘, //enfernt Kennungen für Anzeigenklicks, kein protokollieren von IPs in Ads und Floodlight, entfernt Seiten URL
    ‚analytics_storage‘: ‚denied‘
    })
    // Einwilligungsmodus updaten (allow)
    gtag(‚consent‘, ‚update‘, {
    ‚ad_storage‘: ‚granted‘,
    ‚ads_data_redaction‘: ‚false‘,
    ‚analytics_storage‘: ‚granted‘
    })

    • Hallo Tom,

      vielen Dank für Deinen Kommentar!
      Ich habe die Anpassung an Google Analytics 4 auf dem Zettel aber in der hier dargestellten Form wird GA4 aktuell noch nicht unterstützt. Oder sagen wir mal so: Ich glaube zumindest nicht, dass GA4 unterstützt wird bzw. mit dem Code-Schnippsel einwandfrei funktioniert. Die GA-XXXXXX Property stammt aus einem Tracking-Code den mir ein Kunde mal vor längerer Zeit bereitgestellt hat. Ich hatte dann, das ursprüglich für UA-XXXXXXXX-X vorgesehene Skript, etwas angepasst und anschließend funktionierte es auch mit GA-XXXXXX. Das war allerdings noch vor der Ankündigung von GA4. Meiner Erinnerung nach zumindest.

      Da ich Auftraggebern immer Nahe lege, sich keinen Google-Kram auf die Site zu holen – und die Meisten dieser Empfehlung folgen – hatte ich bislang noch keinen Druck mir GA4 genauer anzuschauen und die beschriebene Opt-In-Lösung zu testen. Somit kann ich Dir da im Moment leider nicht weiterhelfen. Sobald ich da ein Update habe (ich nehme an: in den nächsten Wochen), werde ich das hier veröffentlichen. Falls Du schon eher was hast, lass es mich gern wissen!

      Beste Grüße
      André

      • Hallo nochmal Tom,

        wie sich heraustellte, war die Google Analytics Property mit der ID im Format GA-XXXXXX bereits eine aus Google Analytics 4.
        Der hier gezeigte Code sollte, falls sich nicht inzwischen seitens Osana Änderungen ergeben haben, also auch mit GA4 funktionieren. Zumindest das Aktivieren/Deaktivieren des Scripts nach dem Opt-In sowie das Löschen der Cookies – sofern GA4 nicht im Cookieless-Modus betrieben wird.

        Was das Revoken des Pingings angeht: Wenn im Consent-Banner, mit dem hier beschriebenen Weg, keine Einwilligung erteilt oder die Einwilligung später zurückgezogen wird, wird das Analytics-Skript gar nicht mehr geladen. Damit sollte auch kein Ping mehr an den Server rausgehen (habe ich nicht getestet aber ich wüsste keinen Weg wie das Google bewerkstelligen sollte ohne dass deren Skript geladen wird).

        Wichtig an der Stelle: Auch wenn die Dinger Cookie-Banner heißen, geht es defactor nicht um den Cookie selbst sondern die damit einhergehende Datenverarbeitung. D.h. auch im Cookieless-Modus muss (meinem Verständniss nach) eine Einwilligung eingeholt werden, bevor das Skript geladen wird – auch wenn es keinen Cookie ablegt.

        Beste Grüße
        André

  6. Hallo André,

    ich hatte Dein „alte“ Google Analytics Lösung einige Jahre mit viel Erfolg auf meiner Website implementiert.
    Sie hat ganz wunderbar funktioniert. Vielen, vielen Dank dafür! Nun steht ja der Wechsel zu Google Analytics 4 an und ich bin leider nicht so programmier-erfahren, um Anpassungen selbst vornehmen zu können. Du schreibst, dass Du vor einiger Zeit schon einmal eine GA4 Property (GA-XXXXXX) testweise implementiert hattest. Bevor ich jetzt alles „abreisse“ und neu anpasse, würde ich Dich gerne fragen, wie zuverlässig Deine Lösung im Zusammenspiel mit GA4 ist. Wie ausführlich hast Du sie getestet, ist sie noch aktuell, wirst Du nochmal Zeit darin investieren, lohnt es sich vielleicht für mich, noch etwas zu warten? Bitte verstehe mich nicht falsch: Ich will nicht unverschämt sein und Dich zu etwas drängen, aber Fragen kostet ja nichts. Alternativ überlege ich nämlich, einfach das ganze Google Analytics rauszuschmeissen … Deine Antwort würde mir bei der Entscheidung und Planung sehr helfen. Vielen Dank nochmal! Beste Grüße, Andreas

    • Hi Andreas,

      Deine Frage nach der Zuverlässigkeit kann ich leider nicht abschließend beantworten. In dem Projekt, wo ich das Skript mal in Verbindung mit GA4 genutzt habe, scheint es problemlos zu laufen. Zumindest habe ich keine anderslautende Rückmeldung bekommen (den Opt-In prüfe ich ja selber aber ob die Daten nach Zustimmung auch korrekt bei Google einlaufen, kann ich selber nicht sehen). Vermutlich werde ich mich über kurz oder lang noch mal intensiver damit auseinandersetzen müssen, da in ein paar Projekten auch noch GA3 „verbaut“ ist und diese – sofern es der Auftraggeber möchte – an GA4 angepasst werden müssen. Dann werde ich da sicher noch mal Zeit rein investieren. Wann das sein wird, kann ich Dir allerdings nicht sagen; hängt davon ab ob diese Anpassung beauftragt wird. Meine intrinsische Motivation hält sich dahingehend stark in Grenzen, da ich den GA-Kram persönlich verabscheue (ich aber weiß, dass es plausible Gründe dafür gibt) und stattdessen immer eine selbst-gehostete Matomo-Installation empfehle.
      Wenn Du also auf GA verzichten kannst, ist meine Empfehlung ganz klar: Raus damit.

      Im Rahmen meiner beruflichen Tätigkeit über die Jahre habe ich die Erfahrung gemacht, das viele GA nur einbauen weil sie wissen wollen wieviele Besucher auf Ihre Site kommen, welche Seiten beliebt sind, ggf. noch welche Endgeräte genutzt werden. Mehr als ein paar Mal im Jahr schaut dann aber letztlich doch keiner in die Daten. Dass alles liefert Dir auch Matomo, ohne potentiell sensible oder monetarisierbare Nutzerdaten an Dritte weiter zu geben. Sobald Du jedoch intensiv SEO betreibst, also wirklich intensiv und mit Fokus auf Google, ist GA die bessere Wahl weil Google bewusst einige Metriken (z.B. die eingebenen Suchbegriffe) verscheiert und diese somit nur mit GA auswertbar sind. Außerdem bietet Google eine Kopplung zwischen GA und AdWords – also auch wenn Du Werbeanzeigen bei Google schaltest, ist GA i.d.R. die bessere Wahl. In allen anderen Fällen – und das ist meiner Erfahrung nach die Mehrzahl – reicht Matomo für einen Einblick in die Interessen der Besucher aus.

      Um es noch mal zusammen zu fassen: Eine „bulletproofe“ Zuverlässigkeit kann ich Dir leider nicht zusichern und leider auch keine Versprechen abgeben, wann ich mich noch mal tiefer damit befasse. Das kann nächste Woche sein oder erst in einem Jahr. Oder nie. Wenn Du GA eh nicht intensiv benutzt, schmeiß es raus.

      Beste Grüße
      André

      • Hallo André,

        vielen Dank für Deine schnelle, super ausführliche und ergiebige Antwort! Ich weiß das wirklich zu schätzen und habe jetzt eine sehr gute Entscheidungsgrundlage für mein weiteres Vorgehen. Ein wenig Zeit ist ja noch bis zur großen Umstellung :-) Beste Grüße, Andreas

      • Hallo André, ein kleiner Nachtrag zu meinem obigen Beitrag:

        Ich habe in der Zwischenzeit etwas herumgespielt und festgestellt, dass für die Umstellung auf GA4 fast nichts zu tun ist, es geht eher um kosmetische Dinge. Das liegt daran, dass Google schon seit geraumer Zeit zu einem „alten“ GA3/UA Aufruf parallel einen „neuen“ GA4 Aufruf ausführt, mit automatisch konvertierter GA4-ID, ohne das man diese selber explizit in den Aufruf einsetzen muss. Das bedeutet, dass GA4 auch mit einem „alten“ GA3-Aufruf ohnehin schon (parallel) läuft.

        Die Kosmetik ist nötig, weil es unschön ist, sich dauerhaft auf die automatische Konversion GA3 ID -> GA4 ID zu verlassen. Hierzu muss man bloß im Javascript Code die alten GA3/UA-ID durch die neue (von Google schon erstellte) GA4 ID aktiv ersetzen. Der Code bleibt ansonsten unverändert. (Die neue GA4-ID taucht im Cookie-Namen auf, man kann sie aber auch im Analytics-Dashboard finden.) Zum anderen gibt es bei GA4 weniger Cookies, die auch noch anders benannt sind. Die Liste der bei einem „Revoke“ zu löschenden Cookies muss also noch angepasst werden, was aber auch keine große Sache ist. Voilà! Das wär’s, soweit ich es im Augenblick übersehen kann. Kein großes Ding also! Beste Grüße, Andreas

    • Hi André,

      nach etwas Herumprobieren ist mir mit GA4 noch ein „höllisches“ Problem mit den Cookies aufgefallen. Es gibt bei GA4 2 Cookies, nämlich „_ga“ und „_ga_XXXXXX“, wobei das Letztere ein sehr unangenehmes Verhalten zeigt: Es lässt sich nämlich bei einem Revoke nicht so einfach löschen, bzw. taucht nach dem erfolgreichen Löschen wie aus dem Nichts wieder auf. Ich konnte das mit mehreren Desktop- und Mobil-Browsern reproduzieren. Selbst nach einem kompletten manuellen Zurücksetzen des Browsers kann es beim Laden einer neuen Seite oder bei einfachem Reload wieder von den Toten auferstehen, ein Zombie sozusagen! Auch andere berichten im Netz von diesem nervigen Problem. Ich habe eine Lösung gefunden, das zu beheben und das Cookie tatsächlich in die ewigen Jagdgründe zu schicken. Vielleicht gibt es etwas Einfacheres, aber ich gebe hier mal meine Lösung wieder: Anstatt „deleteGACookies();“ ist jetzt an einigen Stellen eine 3-er Kombi aus „deleteGACookies(); location.reload(); deleteGACookies();“ nötig. Wie gesagt, möglicherweise geht es besser und lässt sich noch weiter konsolidieren, aber vielleicht ist das für manche Leser dieses Threads als erste Hilfe brauchbar. Ich habe meine Lösung gewissenhaft in allen möglichen Konstellationen und Browsern getestet und keinerlei Fehlfunktion mehr festgestellt. Beste Grüße, Andreas

Schreibe einen Kommentar

Personenbezogene Daten interessieren mich nicht – daher ist die Angabe von Name und E-Mail-Adresse freiwillig. Jedoch wird jeder Kommentar von mir geprüft, bevor er freigeschalten wird.