Wie der GA4 DataLayer festlegt, ob Ihre Analysedaten echt sind
Erklärt, wie dataLayer Websites und GTM mit GA4 verbindet, warum reine Events die E-Commerce-Berichterstattung stören und wie Pushes richtig strukturiert und debuggt werden können.
Quellen: **The DataLayer Is the Most Important Thing in Your GA4 Implementation**
Jeder ist besessen von den GA4-Dashboards. Fast niemand kümmert sich um die zehn Zeilen JavaScript, die entscheiden, ob diese Dashboards die Wahrheit zeigen.
Stellen Sie sich ein Szenario vor, das sich wöchentlich in Marketingteams überall wiederholt.
Jemand öffnet GA4 und prüft die Anzahl der add_to_cart-Ereignisse. Es stehen 4.200 dar. Gleichzeitig liegt die Umsatzzahl im E-Commerce-Bericht seltsamerweise nahe bei Null. Verwirrung breitet sich aus. Ein Slack-Thread entsteht. Schließlich ruft jemand „die Person für die Analytik“. Diese Person vermutet bereits, was schiefgelaufen ist, noch bevor sie den Tag Manager überhaupt geöffnet hat.
Ein Ereignis wurde ausgelöst, trug aber keine Informationen bei sich.
Dies ist der häufigste Fehler bei GA4-Einrichtungen – und ironischerweise hat er fast nichts mit GA4 selbst zu tun. Das eigentliche Problem liegt eine Ebene darunter, in einem einfachen JavaScript-Array, das die meisten Anfänger zwar vom Namen her kennen, es aber in der Praxis selten verstehen: das dataLayer.
Dieser Artikel konzentriert sich auf dieses Array. Es handelt sich nicht um eine allgemeine Anleitung zur „Einrichtung von GA4“, sondern um die zentrale Idee, die darüber entscheidet, ob Ihr gesamtes Messsystem zuverlässig ist oder nur kosmetischer Natur.
Zuerst der Überblick
Bevor man Code schreibt, hilft es, den tatsächlichen Weg zu sehen, den die Daten nehmen:
Website
↓
dataLayer
↓
GTM (Google Tag Manager)
↓
GA4
Eine nützliche Analogie ist das Bestellen von Essen in einem geschäftigen, lauten Restaurant:
Die Website ist die Küche – der Ort, an dem die eigentliche Arbeit stattfindet, wie zum Beispiel wenn ein Kunde auf „Zum Warenkorb hinzufügen“ klickt.
Die dataLayer ist das Bestellformular, das der Koch an den Zettel heftet – sie kocht nichts, sondern protokolliert lediglich genau, was zubereitet wurde, für wen und mit welchen Anpassungen.
GTM ist der Server – er liest das Formular, bestimmt, welche Stationen (Tags) die Informationen benötigen, und leitet sie weiter.
GA4 ist die Buchhaltung des Restaurants – sie protokolliert, was geschehen ist, aber nur auf der Grundlage dessen, was tatsächlich auf dem erhaltenen Formular stand.
Falls die Küche einfach nur „Jemand hat etwas bestellt!“ in den Raum ruft, ohne einen schriftlichen Auftrag vorzulegen, hat der Kellner nichts Konkretes zu übermitteln, und das Protokoll zeigt schließlich ein leeres Häkchen anstelle einer tatsächlichen Transaktion an. Dieser vage Ruf ist genau das, was ein reines, parameternloses Ereignis in der Praxis darstellt. Der Bestellzettel – also der dataLayer-Push – ist es, der die gesamte Konfiguration in ein echtes System verwandelt und sie nicht zu einem Ratespiel macht.
Was dataLayer eigentlich ist
Sobald man den Fachjargon weglässt, ist dataLayer nichts anderes als ein einfacher JavaScript-Array, der an window gebunden ist und in den Ihre Website einfache Objekte einfügt. Das ist das gesamte Prinzip. Es gibt keinerlei eingebaute Verbindung zu Google – zumindest nicht, bis das Container-Skript von Tag Manager einen Zuhörer daran anhängt.
Die Initialisierung sieht in der Regel so aus: window.dataLayer = window.dataLayer || [];
Diese eine Zeile bewirkt etwas Subtileres, als es auf den ersten Blick scheint. Sie erstellt nicht einfach blind einen neuen Array und wirft alles, was bereits darin ist, weg – stattdessen wird geprüft, ob bereits ein Array vorhanden ist, und nur dann wird ein neues initialisiert, wenn keines existiert. Dieser genaue Fehler wurde wiederholt von langjährigen GTM-Praktikern hervorgehoben: Wenn man direkt mit einem einfachen = auf dataLayer zugreift, anstatt etwas hinzuzufügen, stört man stillschweigend das von GTM genutzte Mechanismus, da GTM die native push()-Methode des Arrays überschreibt, sobald sein Container-Skript geladen ist. Machen Sie diesen Fehler einmal – und das tun fast alle –, können Sie einen ganzen Nachmittag damit verbringen, sich über einen Container zu wundern, der „einfach nicht funktioniert“, ohne dass es Fehler gibt, die auf die Ursache hinweisen.
Nachdem das Skript von GTM auf einer Seite ausgeführt wurde, verbindet es sich mit der push()-Methode. Ab diesem Zeitpunkt wird jedes Objekt, das Sie über diese Methode senden, in GTM’s internes Datenmodell eingebettet – die Struktur, die tatsächlich seine Variablen und Auslöser steuert. In der Praxis achtet GTM kaum noch auf den Roharray selbst, sondern beobachtet stattdessen den Eingangspunkt, durch den jede Übertragung erfolgt.
Warum sollte sich ein Anfänger dafür interessieren? Weil dies das Verständnis davon verändert, was ein Aufruf von dataLayer.push() tatsächlich bedeutet. Sie „senden kein Ereignis an Google Analytics“. Stattdessen erfassen Sie eine strukturierte, mit Zeitstempel versehene Information im eigenen Speicher Ihrer Website – eine Information, die später von jedem nachgeschalteten Tool genutzt werden kann, sei es GTM, eine Kundendatenplattform, Facebooks Pixel oder ein Analysetool, das Sie noch nicht einmal eingeführt haben. GA4 ist lediglich einer von vielen Nutzern.
Warum es überhaupt ein dataLayer gibt
Eine berechtigte Frage hier: Warum nicht einfach die Tracking-Funktion von GA4 direkt im onclick-Handler einer Schaltfläche auslösen? Die Leute haben das jahrelang genau so gemacht, als analytics.js und gtag.js noch der Standard waren. Im engeren Sinne funktioniert das. Doch es ist anfällig – gerade in dem Punkt, der wichtig wird, sobald man skaliert.
Der dataLayer existiert, um zwei Dinge trennen zu können, die niemals eng miteinander verbunden sein sollten: was tatsächlich auf der Website passiert und welches Analysetool zu diesem Zeitpunkt gerade aktiv ist.
In seinem Kern dient ein dataLayer dazu, alle Informationen zu speichern, die Sie von Ihrer Website an jedes verbundene Tool weitergeben möchten – und der Grund für seine Existenz ist, dass das Direktabrufen derselben Daten aus der Seitenmarkierung unzuverlässig ist, da sich diese Markierung aus Gründen ändern kann, die überhaupt nichts mit der Tracking-Funktion zu tun haben. Mit anderen Worten: Ihr Produktteam sollte frei sein, die „Zum Warenkorb“-Schaltfläche umzudesignen, ihre Klasse zu ändern oder sie in einem Modal-Fenster zu verbergen, und Ihre Tracking-Einrichtung sollte dies weder bemerken noch beeinflusst werden – schließlich hat sie die Schaltfläche von Anfang an nicht gelesen. Sie las vielmehr eine absichtlich, ausdrücklich erstellte Beschreibung dessen, was stattgefunden hat.
Das ist der grundlegende Unterschied zwischen dem Zwang, Hinweise aus einer Seite herauszuholen, und der direkten Bereitstellung der Fakten. Der erzwungene Ansatz bricht zusammen, sobald sich die Struktur der Seite ändert. Die direkte Bereitstellung der Fakten übersteht Neugestaltungen, A/B-Tests, Framework-Migrationen sowie Personalwechsel, denn die Vereinbarung befindet sich im Push selbst und nicht irgendwo im DOM.
Nun der Code, der alles verändert
Hier ist der in dem Brief beschriebene Push:
Vergleichen Sie das mit dem, was ein Neuling normalerweise tut: Er verbindet eine GTM-Tag direkt mit einem Klickevent, überspringt das dataLayer-Objekt völlig und verwendet einen Auslöser, der im Grunde besagt: „Wenn jemand auf diese Schaltfläche klickt, sendet die add_to_cart-Tag an GA4.“
Auf den ersten Blick scheinen beide Methoden „ein add_to_cart-Event zu erzeugen“. Wenn man den Echtzeitbericht von GA4 öffnet, könnte man in jedem Fall eine identische Zeile mit dem Label add_to_cart sehen. Genau das macht den Unterschied zwischen ihnen so riskant: Er bleibt verborgen, bis jemand versucht, die Zahlen abzurufen, die eigentlich mit diesem Event einhergehen sollten.
Hier ist der eigentliche Unterschied im Detail dargestellt:
Ehrlich gesagt ist diese einzige Tabelle die Zusammenfassung des ganzen Themas. Ein Event ohne angehängte Parameter ist lediglich ein Etikett, das von nichts gestützt wird. Es handelt sich dabei um den Unterschied zwischen einem Zeugen, der sagt „etwas ist passiert“, und einem, der sagt „ein roter Sedan ist um 16:12 Uhr durch die Ampel gefahren“. Nur die zweite Version hält vor Gericht stand, und nur die zweite Version hilft Entscheidungsträgern dabei zu entscheiden, ob eine Produktlinie weiterhin finanziert werden sollte.
Ereignis versus Parameter: Die Grenze, die Anfänger nicht erkennen
In GA4s Modell enthält jeder Aufruf genau einen Ereignisnamen (add_to_cart) sowie, sofern richtig verwendet, eine Reihe von Ereignisparametern (product_id, product_name, price usw.).
Das Ereignis gibt an, welche Kategorie von Vorgang stattgefunden hat. Die Parameter liefern die detaillierten Informationen zu diesem spezifischen Vorkommnis.
Anfänger betrachten den Ereignisnamen oft als wäre er die vollständige Erklärung. Das ist nicht der Fall – es handelt sich dabei lediglich um die Überschrift. Allein add_to_cart sagt fast nichts Entscheidendes: nicht, um welches Produkt es geht, nicht dessen Preis, nicht welche Warenkorb- oder Währungseinstellungen relevant sind, und auch nicht, ob die Aktion auf einer Suchseite oder innerhalb eines Karousells mit verwandten Produkten begann. All diese Antworten finden sich in den Parametern, und keine davon wird automatisch bereitgestellt – GA4 verfügt nicht über die Möglichkeit, diese Informationen selbst abzuleiten, zu erraten oder auszuwerten.
Dies erklärt auch, warum das einfache „Erstellen eines Events“ mithilfe der Wizard-Funktionen für Tags und Auslöser in GTM, ohne dass Variablen konfiguriert werden, zu einem scheinbar vollständigen Ergebnis führt, das strukturell jedoch leer ist. Das Event wird ausgelöst, der Bericht zeigt eine Zeile an – alles scheint in Ordnung zu sein – bis jemand nach dem durchschnittlichen Wert der Artikel im Warenkorb im letzten Monat fragt; zu diesem Zeitpunkt gibt es nichts mehr, womit man antworten könnte.
E-Commerce-Daten: Wo das Auslassen dieser Schritte keine Option mehr ist
Normale Nutzungsereignisse wie Seitenaufrufe, Scrollverfolgung oder allgemeine Klicks können etwas weniger detailliert sein. E-Commerce-Ereignisse hingegen nicht. Die gesamte E-Commerce-Berichterstattung von GA4 – einschließlich Umsatzangaben, Anzahl der Produktansichten, Verhältnis von Warenkorbzusätzen zu Kaufen sowie Leistungsdaten pro Produkt – hängt davon ab, dass Ereignisse wie add_to_cart, view_item, begin_checkout und purchase zusammen mit einem ordnungsgemäß strukturierten items-Array sowie Transaktionsparametern vorliegen.
Falls bei einem Kaufvorgang, der in den dataLayer übertragen wird, ein items-Array fehlt, das für jeden Artikel den item_id, item_name, Preis und die Menge enthält, behebt GA4 diese Lücke nicht stillschweigend. Seine E-Commerce-Berichte zeigen Nullwerte sowie leere Zellen direkt neben einer Transaktionsanzahl, die eindeutig nicht null ist. Dieses spezifische Ungleichgewicht – registrierte Transaktionen, aber kein Umsatz – gehört zu den am häufigsten gemeldeten Problemen in GA4-Installationen, und es lässt sich fast immer auf ein und dasselbe zurückführen: Ein unvollständiges Objekt wird in den dataLayer übertragen.
Deshalb befolgen ausgereifte Implementierungen das von Google definierte ecommerce dataLayer-Schema und erfinden keine eigenen Feldnamen. Es handelt sich dabei nicht um Bürokratie um der selbst willen; es ist eine gemeinsame Sprache, die zwischen Ihrer Website, den eingebauten E-Commerce-Variablen von GTM und den E-Commerce-Berichten von GA4 verwendet wird. Weichen Sie von diesem Schema ab – indem Sie beispielsweise ein Feld als item_price statt price benennen oder ein Objekt einen Level tiefer einbetten, als erwartet –, dann können die eingebauten Variablen Ihre Werte einfach nicht finden, obwohl die Daten technisch gesehen vorhanden sind.
Custom Variablen: GTM dazu bringen, Ihr Event korrekt zu lesen
Sobald die Informationen auf die richtige Weise in den dataLayer gelangen, benötigt GTM immer noch Anweisungen darüber, wo er sie finden kann. Dafür ist eine Data Layer Variable zuständig: ein benannter Referenzwert, der GTM anweist, nach einem bestimmten Schlüssel – beispielsweise „price“ – innerhalb des gerade eingefügten Objekts zu suchen und diesen Wert an alle Tags weiterzuleiten, die danach fragen.
Wenn etwas in den dataLayer eingefügt wird, durchsucht GTM nicht das Roharray selbst, um Variablen zu füllen. Stattdessen liest es aus seinem eigenen internen Datenmodell, das durch diese Eingabe aktualisiert wird. Data Layer Variablen beziehen sich auf dieses interne Modell und nicht direkt auf das Array, wodurch die Variablenauflösung von GTM geschützt wird, falls ein anderes Skript später dieses Array umordnet oder überschreibt.
Praktisch gesehen bedeutet das, dass für jedes Feld, das Sie übertragen – wie z. B. product_id, product_name und price – jemand, der Zugriff auf den GTM-Container hat, eine entsprechende Data Layer Variable erstellen muss und diese anschließend mit dem relevanten Parameterfeld in der GA4-Event-Tag verknüpfen muss. Überspringen Sie diesen Schritt, spielt es keine Rolle, wie gründlich die Übertragung in dataLayer war: GTM wird das Event trotzdem genau nach Anweisung auslösen, aber keine der unterstützenden Details weiterleiten, einfach weil ihm nicht mitgeteilt wurde, welche Felder abgerufen werden sollen.
Das ist der zweite häufige Fehlerpunkt, direkt nach unvollständigen oder fehlenden Übertragungen, bei dem Teams ihre Daten verlieren: eine korrekt erstellte dataLayer-Übertragung, gefolgt von einem GTM-Tag, der nie so konfiguriert wurde, dass er tatsächlich daraus liest.
Debugging: Wie man all das überprüfen kann
Glauben Sie niemals blind daran, dass Ihr dataLayer das tut, was Sie denken. Beobachten Sie den Vorgang selbst. Zwei Tools machen das einfach:
- GTM’s Vorschaumodus. Er zeigt jede abgerufene Tag, jeden überprüften Auslöser und vor allem jede einzelne dataLayer-Ausgabe in der Reihenfolge, wobei der vollständige Inhalt jedes Objekts zur Ausführung bereitsteht. Wenn der Preis in der hier angezeigten Ausgabe fehlt, wird er niemals in GA4 gelangen – und keine Anpassung Ihrer GTM-Einstellungen wird dieses Ergebnis ändern.
Eine gute Gewohnheit, die man sich aneignen sollte: Bevor man annimmt, dass GTM bei der „Verfolgung von etwas“ versagt, sollte man zunächst die Konsole überprüfen und sich den dataLayer ansehen. Wenn der Auftrag nie erteilt wurde, kann man dem Koch nicht vorwerfen, dass er nichts zubereitet hat.
Es gibt noch einen weiteren, weniger offensichtlichen Fehlerspeicherungsfall, auf den hingewiesen werden sollte: GTMs internes Datenmodell speichert nur den neuesten Wert, der für eine bestimmte Schlüsselwerte gesendet wird. Wenn also zwei separate Skripte auf derselben Seite vor dem Auslösen Ihres Tags Werte unter einem identischen Schlüssel senden, die miteinander kollidieren, überschreibt dasjenige Skript, das zuletzt ausgeführt wird, stillschweigend den anderen. Dies ist eine häufige Ursache dafür, dass die Tracking-Funktionen während der Tests einwandfrei funktionieren, in der Produktion jedoch versagen – meist weil irgendein Drittanbieter-Skript außerhalb Ihrer Kontrolle nach Ihrem eigenen Skript seine eigenen Daten sendet.
Datenqualität: Der Teil, der das Unternehmen tatsächlich schützt
Alles, was bisher besprochen wurde, dient einem einzigen Ziel: der Erstellung von Daten, die ausreichend zuverlässig sind, um darauf eine echte Entscheidung zu treffen.
„Verwenden Sie immer .push() mit dataLayer.“ — Simo Ahava, Experte für Google Tag Manager
Das ist eine enge technische Regel, doch sie steht für etwas Größeres. Analyseteilungen kollabieren selten auf einmal. Sie zerstören sich schrittweise, durch eine fehlerhafte Schlüsselangabe oder ein übersprungenes Feld nach dem anderen, bis ein einst zuverlässiger Bericht einfach nicht mehr zuverlässig ist – oft, ohne dass jemand den genauen Zeitpunkt bemerkt.
Mehrere Praktiken unterscheiden eine Implementierung, über die tatsächlich Berichte erstellt werden können, von einer, die nur funktional erscheint:
- Konsistente Benennung. Wenn ein Feld heute product_id heißt, nach dem nächsten Sprint productId und bei einer späteren Überarbeitung item_id, entstehen drei inkompatible Datensätze, die nicht in einer einzigen Abfrage zusammengeführt werden können.
Die Behandlung der Datenqualität als einmaliger QA-Check erfasst den Kern des Problems nicht. Es handelt sich dabei eher um eine Art Rohrleitungsanlage: Solange alles richtig funktioniert, wird es nicht bemerkt, doch sobald es versagt, wird es plötzlich sehr auffällig und äußerst kostspielig.
Fazit
Die eigentliche Quelle der Verwirrung liegt weder in GA4 noch in GTM, obwohl beide ständig die Schuld dafür bekommen. Es kommt auf eine einfachere Frage hinaus: Hat Ihre Website jemals klar dokumentiert, was tatsächlich geschehen ist?
Die Aufrufung von dataLayer.push({ event: "add_to_cart", ... }) ist kein unbedeutender technischer Aspekt, und sie ist auch nicht gleichzusetzen damit, einen GTM-Einrichtungswizard durchzuführen und anzunehmen, die Arbeit sei erledigt. Es geht um den Unterschied zwischen einem Unternehmen, das genau angeben kann, was seine Kunden getan haben und wie viel diese Aktivitäten wert waren, und einem Unternehmen, das nur mit den Schultern zucken kann und behauptet, etwas habe viertausendzweihundert Mal stattgefunden, ohne zu wissen, was.
Die Dashboards befinden sich weiter flussabwärts in der Kette. Im dataLayer wird zunächst die Wahrheit – oder zumindest die Annahme, die ihrer Stelle tritt – festgehalten.
Wenn ein GA4-Bericht das nächste Mal nicht zusammenpassen zu scheinen scheint, überspringen Sie die GA4-Oberfläche. Öffnen Sie die Konsole, geben Sie dataLayer ein und lesen Sie sich den Eintrag selbst an.