Laut Datenschutz-Grundverordnung ist es notwendig, bei der Verwendung von Marketing- und Werbe-Cookies explizit ein Einverständnis des Nutzers einzuholen. Dafür gibt es unterschiedliche technische Lösungen – von CMS-Plugins bis hin zu kostenpflichtigen, professionellen JavaScript-basierten Lösungen.
Für die Einbindung von Marketing-Tags ist der Google Tag Manager eine häufig verwendete Lösung. Er vereinfacht die Verwaltung einer Vielzahl von Tags. Persönlich nutze ich ihn vor allem in Kombination mit Google Analytics und Google Optimize.

Mit wenigen Codezeilen lässt sich auch ein einfacher Cookie-Banner in Google Tag Manager realisieren. Wichtig ist dabei, dass alle Marketing-Tags erst nach „Akzeptieren“ des Banners geladen werden (Optin). Möglich wird dies durch die Verwendung des DataLayer von Google Tag Manager. Vorteile sind eine geringe Codegröße, dadurch schnellere Ladezeiten und vor allem der Verzicht auf CMS-Plugins, die einen Einfluss auf Ladezeit haben und potenziell Sicherheitslücken hervorrufen können.
Im folgenden wird davon ausgegangen, dass bereits ein Google-Analytics-Tag in Google Tag Manager angelegt ist und mit dem Trigger „All Pages“ ausgelöst wird (d.h. nicht datenschutzkonform eingebaut ist).
Schritt 1: Cookiebanner-Tag anlegen
Zu Beginn wird in Google Tag Manager ein neues „Benutzerdefiniertes HTML-Tag“ angelegt. Benannt kann es etwa mit „Cookie-Banner-Tag“ werden, als Trigger wird der „All Pages“-Trigger verwendet. Dadurch wird das HTML-Tag bei jedem Seitenaufruf geladen.

Folgender Code wird unter „HTML“ eingefügt. Wichtig ist, in Zeile 44 und 59 die eigene Domain einzufügen. In Zeile 59 sollte der Punkt vor dem Domainnamen bestehen bleiben. Eine detaillierte Erklärung des Codes folgt im letzten Abschritt des Artikels. Anschießend kann das Tag gespeichert werden.
<style> .cookie-banner { padding: 0.5em; position: fixed; z-index: 9999999; bottom: 0; background-color: #04378b; color: #fff; border-top: 1px solid #ccc; width: 100%; display: none; flex-direction: row; justify-content: space-between; flex-wrap: nowrap; align-items: center; } .cookie-banner a { color: #fff; text-decoration: underline; } .control { flex-shrink: 0; } .cookie-banner button { padding: 1em; background: #8C1257; color: white; border: none; } .small { font-size: 12px; } .small:hover, .cookie-banner button:hover { cursor: pointer; } </style> <div class="cookie-banner" id="cookie-banner"> <div class="text"> Verwendung von Cookies: Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, nutzen wir Cookies. <a href="https://meine-domain.de/datenschutzerklaerung/">Mehr erfahren: Datenschutzerklärung</a>. </div> <div class="control"> <button onclick="acceptCookies();"> Cookies zulassen </button> <span class="small" onclick="denyCookies()"> Ablehnen. </span> </div> </div> <script> function acceptCookies() { var x = document.getElementById("cookie-banner"); document.cookie = "cookieconsent=True;max-age=31536000;domain=.DOMAIN-NAME-HIER-EINGEBEN-PUNKT-BESTEHEN-LASSEN.de;path=/"; dataLayer.push({'event':'user_cookie_consent'}); x.style.display = "none"; } function denyCookies() { var x = document.getElementById("cookie-banner"); x.style.display = "none"; } function initializeBanner() { var cookieString = document.cookie; if(cookieString.includes("cookieconsent=True")){ dataLayer.push({'event':'user_cookie_consent'}); } else { var x = document.getElementById("cookie-banner"); x.style.display = "flex"; } } // In some cases, the GTM code is not ready yet when DOMContentLoaded is called - in this case, the code must be executed right away, as DOMContentLoaded won't fire again if(document.readyState === "complete" || document.readyState === "interactive") { initializeBanner(); } else { document.addEventListener("DOMContentLoaded", function(event){ initializeBanner(); }); } </script>
Schritt 2: Neuer Trigger: Cookies akzeptiert
Google Analytics (und alle anderen Marketing-Tags) sollen erst beim Feuern des Tag Manager-Events „user_cookie_consent“ geladen werden. Dieses wird in Zeile 72 des obigen Codes in den DataLayer injiziert. Um auch in Google Tag Manager auf das Feuern dieses Events zu warten, muss ein neuer Trigger angelegt werdne. Als Triggertyp wird „Benutzerdefiniertes Ereignis“ ausgewählt, der Name kann z.B. „Cookies akzeptiert“ lauten. Wichtig ist der „Ereignisname“ – dieser muss „user_cookie_consent“ lauten.

Schritt 3: Auslösende Trigger der Marketing-Tags ändern
Anschließend müssen unter „Tags“ noch alle Marketing-Tags (z.B. Google Analytics) so eingestellt werden, dass als „Auslösender Trigger“ der gerade erstellte „Cookies akzeptiert“-Trigger zum Einsatz kommt. Das kann dann zum Beispiel so aussehen:

Jetzt müssen die Ergebnisse nur noch durch Klick auf „Senden“ veröffentlicht werden! Es bietet sich an, die Ergebnisse durch Verwendung des Chrome Tag Assistent zu überprüfen.
Was macht der neu eingefügte Code eigentlich?
Das HTML-Tag besteht zunächst einmal aus vielen Styling-Informationen für den Cookie-Banner selbst (Zeile 1-40) sowie den entsprechenden HTML-Code (Zeile 42-56). Dieser kann nach belieben angepasst werden – der obige Code bietet Mobil wie auf dem Desktop eine relativ gute Darstellung.
Die Funktion acceptCookies setzt selbst einen Cookie, der dafür sorgt, dass der Cookie-Banner nach Akzeptieren des Banners nicht erneut angezeigt wird. Darüber hinaus wird das entsprechende Event in den DataLayer injiziert (gepusht), auf welches GTM „hört“ und anschließend die entsprechenden Marketing-Cookies läd. Der Banner wird anschließend versteckt.
In denyCookies wird einfach nur der Banner versteckt. Wer auch dafür sorgen möchte, dass Nutzer nicht erneut um eine Einwilligung gebeten werden, sollte noch Zeile 59 kopieren und „cookieconsent=True“ durch „cookieconsent=False“ ersetzen.
InitializeBanner wird nach Laden der Seite aufgerufen. Hier wird zunächst überprüft, ob bereits eine Einwilligung gegeben wurde. In diesem Fall wird direkt das user_cookie_consent-Event gefeuert. Andernfalls wird der Banner dargestellt. Ggfs. wäre weitere Code erforderlich, um den Cookie-Banner nicht anzuzeigen, falls ein Nutzer eine Einwilligung explizit abgelehnt hat.
In den Zeilen 80 bis 88 wird in jedem Fall darauf gewartet, dass das DOM bereits geladen ist („DOMContentLoaded“). Es kann aber auch vorkommen, dass der GTM-Code erst geladen/initialisiert wird, wenn das DOM bereits fertig aufgebaut ist.