Markus Baersch

Analytics · Beratung · Lösungen

Start » Blog » Analytics

13.12.2022

Wer auf Google Analytics 4 setzt, kommt an der Standardmethode der Datenerhebung im Browser mit Hilfe von gtag.js kaum vorbei. Weder bei direkter Implementierung, noch unter Verwendung des Google Tag Managers. Im Normalfall holt gtag.js individuelle Einstellungen des GA4 Kontos in den Browser, sammelt Daten und versendet diese entweder direkt an Google Analytics oder einen serverseitigen Google Tag Manager. Ein Ersatz scheint schwierig - aber ist nicht unmöglich! Mit walker.js steht eine Alternative bereit, die jüngst in einer neuen Version erschienen ist, welche den Einsatz als gtag.js Ersatz vereinfacht. Vor allem im Zusammenspiel mit einem server-side GTM erhält man einen vielseitig einsetzbaren Datenstrom, der (nicht nur) für GA4 geeignet ist.

Warum überhaupt wechseln?

Wenn GA4 gern Daten über gtag.js sammeln möchte - warum sollte man überhaupt über Optionen nachdenken? Schlussendlich kann man gtag.js bei Einsatz eines ssGTM als First Party Script in den Browser bekommen und so viele Probleme umgehen, ohne eine andere Lösung zu nutzen. Zudem unterstützt man (nur) so viele Funktionen und Einstellungen von GA4. Der Browser weiß dank gtag.js eine Menge:

  • Was ist eine Conversion?
  • Welche Domains stehen auf der Ausschluss-Liste?
  • Was soll als internal oder dev Traffic markiert werden?
  • Welche Ereignisse sollen geändert oder auf Basis anderer Ereignisse erstellt werden?

Dazu kommen weitere Dinge wie z. B. die Unterstützung von Remarketing (client- und serverseitig), Speichern von Click-Ids, Verwaltung von Cross Domain Tracking. Das alles zu ersetzen, ist schwierig. Und in einzelnen Aspekten sogar mehr oder weniger unmöglich.

Es gibt trotzdem einige gute Gründe, warum eine Alternative Form der Datenerhebung im Browser angestrebt werden sollte. Sei es, weil andere Scripts leichtgewichtiger sind. Oder um auch dann eine Lösung zu haben, um Events an den eigenen Tagging-Server zu melden, wenn keine Zustimmung zur Verwendung von Google Analytics besteht. Und zwar ohne den zweifelhaften Consent Mode nutzen zu müssen.

Was ist walker.js?

walker.js ist eine Open Source Lösung zum Tagging im Browser und der Generierung von Events. Unter elbwalker.com finden sich Beispiele, eine Demo und ausführliche Dokumentation. Ich habe walker.js zur Datenerhebung im Browser im Rahmen meines First Party Data Workshops vor allem im ersten Teil eingesetzt, um die prinzipiellen Möglichkeiten aufzuzeigen, die in einer unabhängigen Datensammlung und Auswertung liegen.

Genau hier zeigt sich ein Hauptargument für den Verzicht auf gtag.js im Browser: Wer nicht nur Google Analytics 4 vom ssGTM aus mit Daten versorgen möchte, bekommt nur bei Zustimmung zu Google Analytics Daten am eigenen Endpunkt (oder muss auf den Consent Mode setzen, was ich aus verschiedensten Gründen sehr kritisch finde). Events und Seitenaufrufe für alternative Tools wie Matomo, Piwik PRO oder eben eine eigene Datenbank fallen somit weg, wenn man keinen Datenstrom aus dem Browser etablieren kann, der unabhängig von Consent funktionieren kann und darf.

Der Einsatz für Google Analytics 4... und mehr

Dieser Beitrag zeigt, wie walker.js Events aus einem client-seitigen Google Tag Manager versendet und danach an einem server-seitigen Google Tag Manager empfangen, verarbeitet und an GA4 weitergegeben werden. Oder - z. B. bei fehlendem Consent - an andere Dienste meldet bzw. direkt als Rohdaten in einer BigQuery Tabelle speichert.

Part I: Tagging im Browser

walker.js kennt zwei unterschiedliche (parallel nutzbare) Wege, um Events wie Seitenaufrufe, Klicks, Scrollvorgänge, E-Commerce Ereignisse oder alles andere zu erzeugen, was typischerweise auf einer Website oder in einer App zu vermessen ist. Das Ergebnis sind Ereignisdaten in einer vorgegebenen, aber flexiblen Objekt-Struktur mit verschiedenen Schlüsseln, in denen die Daten landen - entweder automatisch oder durch Konfiguration des "walkers" bzw. der Ereignisse selbst.

walker.js Event Beispiel

Der "primäre" Weg zum Tagging ist die Verwendung von Attributen im Quellcode der Seite. Dieses System hat unbestreitbare Vorteile, ist aber für die Umstellung des Taggings bei einer bestehenden Website eher selten realistisch machbar. Vielmehr gibt es i. d. R. eine bestehende Struktur, einen dataLayer und einen Tag Manager, die gemeinsam für die Versorgung von Google Analytics mit Daten sorgen. Auf dieser Basis werden die folgenden Hinweise eine exemplarische Umstellung aufzeigen. Dennoch: Die Grundlagen des Taggings über den DOM werden im o. a. Workshop gezeigt und stehen auf der elbwalker Website sogar im Vordergrund.

Für die meisten Fälle wird ein Tagging über JavaScript erfolgen (müssen), ohne dass man sich auf das Vorhandensein bestimmter Elemente auf den Seiten verlassen kann, die passend für walker.js mit Attributen versehen sind. Um Universal Analytics oder GA4 Tags im GTM zu ersetzen, bietet sich daher vor allem ein GTM Event-Tag für walker.js an. Das Feedback auf den Workshop und eine Vorstellung der grundlegenden Funktionsweise auf dem Measurecamp Brüssel haben deutlich aufgezeigt, dass nur auf diese Weise ein möglichst hürdenfreier Weg für die Integration in bestehende Tracking Setups möglich ist, die derzeit noch auf gtag.js setzen (müssen).

Obschon sowohl vom elbwalker Team als auch Justus Blümer und mir in den letzten Wochen parallel an verschiedenen Teilen des Puzzels gearbeitet wurde, dass wir gemeinsam für einen möglichst reibungslosen Einsatz von walker.js im GA4 Kontext zusammengesetzt haben, ist erst mit den letzten Anpassungen der neuen Version 1.6.0 von walker.js und dem Event-Tag-Template ein rundes Bild entstanden.

Tagging mittels GTM Event Template

Damit die Implementierung von walker.js im Wesentlichen genau so ablaufen kann, wie die Integration eines beliebigen anderen Tracking-Dienstes, können alle zu vermessenden Events mit einem weiteren Tag abgedeckt werden. Wo ein Seitenaufruf, Klick oder Kauf in einem Tag Manager zur Auslösung von Tags für mehrere Dienste konfiguriert ist, kommt mit walker.js üblicherweise zunächst ein weiteres Tag hinzu. Mittelfristig soll und wird dieses Tag dazu dienen können, das Tagging für den eigenen server-side GTM mit GA4 Tags zu ersetzen, aber ein Parallelbetrieb ist - zumindest auf einer Staging Umgebung - zur Erprobung und Validierung - normalerweise zu empfehlen. So kann in einer zweiten GA4 Property ein Pool für Datenvergleiche angelegt werden, bis eine Umstellung auf walker.js Events als primäre Datenquelle reibungslos verlaufen kann.

Wird ein Tracking komplett neu aufgebaut, kann man hingegen direkt voll auf walker.js setzen und direkt auf GA4 Tags verzichten.

Installation des Tag Templates

Um das Event-Tag zu nutzen, ist (derzeit) eine manuelle Installation erforderlich. Dazu die Datei template.tpl aus dem Github Repository des Tag Templates herunterladen, im GTM unter "Vorlagen" einen neuen Eintrag für ein Tag Template anlegen und dann die gespeicherte Datei über das Drei-Punkte-Menü mittels "Vorlage importieren" einlesen. Nach dem Speichern steht dann bei der Anlage eines neuen Tags ein "walker.js Event" zur Verfügung.

walker.js laden und konfigurieren

Damit das Event nicht nur entsteht, sondern auch verarbeitet werden kann, muss das walker.js Script auf einer nutzenden Website geladen und konfiguriert werden. Das kann auf unterschiedliche Weise geschehen.

  • Direkte Implementierung
  • Laden und Konfigurieren mittels HTML Tag in GTM
  • Verwendung eines weiteren "walker.js Configuration" Templates
  • Mischbetrieb der vorangestellten Optionen

Wer die Möglichkeit hat, walker.js auf dem eigenen Server abzulegen und im Quellcode aller Seiten zu laden und ein Script zur Konfiguration zu hinterlegen - genauso, wie man es beim direkten Einbau von gtag.js oder anderer Trackingdienste tun würde -, der kann das tun, ohne dass dadurch automatisch und unkontrolliert Daten fließen. Denn einer der Vorteile von walker.js ist die Tatsache, dass die Reihenfolge von Konfiguration, Auftreten von Events und Änderungen der Consent-Lage keine wesentliche Rolle spielt.

Üblicher wird es allerdings sein, das Laden und die Konfiguration im Tag Manager unterzubringen, denn dazu ist er schlussendlich gedacht und bereits implementiert. Den meisten Komfort dazu bietet das zusätzliche Konfigurations-Tag Template im Github-Repository. Weil dieser Weg allerdings ein wenig mehr Erklärung benötigt, sei hier auf die Hilfe zu diesem Template auf Github und das (kommende) Video zu diesem Blogpost verwiesen, wo diese Variante demonstriert wird.

Dieser Blogpost zeigt stattdessen ein "Benutzerdefiniertes HTML" Tag mit dem Inhalt der Basiskonfiguration aus dem Beispiel im Repository. Mit diesem überschaubaren Code kann mit wenigen Anpassungen die gewünschte Fassung von walker.js geladen, initialisiert und mit einer "Destination" verstehen werden, die alle Ereignisse einschließlich der bestehenden Consent-Lage an den ssGTM sendet.

Konfiguration per HTM Tag

Im oberen Bereich des Scrips, das per Copy & Paste in ein neues HTML Tag im GTM übernommen wird, kann die Anpassung der Konfiguration geschehen.

walker.js Beispiel-Konfiguration

Die Optionen sind überschaubar: Jede Konfiguration des Trackings im Browser kann mit einer Version via "setup_version" versehen werden, die jedem Event beigefügt und auf Wunsch als Dimension an GA4 übergeben werden kann, was bei Problemen nach Anpassung der Konfiguration hilfreich sein mag. Wesentlich sind eher die folgenden Optionen. Darin wird zunächst der Pfad unter "setup_endpointUrl" definiert, an den die Events gesendet werden sollen. Das ist die Adresse des eigenen server-side GTM inkl. eines Pfads zur Adressierung des Clients. Da dieser im folgenden Schritt erst installiert werden muss, kann für die Erprobung einstweilen httpbin.org/anything als Ziel beinhalten werden, so dass in der Netzwerkübrsicht des Browsers bei Bedarf die gesendete und von diesem Service zurückgesendete Nutzlast kontrolliert werden kann.

  • Die beiden Optionen zum Format "setup_sendAsImage" und "setup_sendBase64" bestimmen, ob ein GET Request (="image") oder POST Request verwendet werden soll und ob die Nutzlast dabei Base64 codiert werden soll. Der Client (siehe unten) wird alle möglichen Kombinationen dieser Einstellungen verstehen. Sie dienen primär dazu, bei Problemen mit CORS Fehlern als Fallback mit GET statt dem üblichen POST zu arbeiten und können in 99% der Fälle in den bestehenden Einstellungen übernommen werden.
  • Als "setup_walkerpath" wird angegeben, ob und woher walker.js durch das Tag geladen werden soll. Voreingestellt ist das Laden von einem CDN - das will man i. d. R. vermutlich lieber vom eigenen Server erledigen, was entweder durch Eintragen des Pfads einer lokalen Kopie geschehen kann oder - nach Installation des Clients a, ssGTM - auch über den eigenen Tagging-Server. Zur ersten Erprobung kann die CDN Adresse beibehalten werden.
  • Der Platzhalter "setup_useSessionData" ist schließlich dafür zuständig, ob und wie die Ereignisse mit persistenten Daten zu User und Session versehen werden. Dazu ist im Script weiter unten eine Beispiel-Implementierung zu finden, die man anpassen kann bzw. sollte, weil hier z. B. mit localStorage und sessionStorage gearbeitet wird. Diese Lösung ist nur dann zu verwenden, wenn nur ein einzelner Host (also z. B. nur www.meinedomain.de, aber nicht zusätzlich blog.meinedomain.de oder andere Subdomains) im Spiel ist. Will man die bestehende Lösung beibehalten, sind zumindest sowohl die bestehenden Schlüssel für die Daten im Browserspeicher den eigenen Cookie-Hinweisen hinzuzufügen (wenn es diese gibt) und die Variable  "setup_useSessionData" sollte nur dann auf true stehen, wenn auch Zustimmung besteht. Je nachdem, wie dieses Tag mit Zustimmung versehen wird, muss demnach das Triggern dieses Setup-Tags für walker.js gesteuert werden.

Damit ist die Konfiguration abgeschlossen und der Container kann in die Vorschau versetzt werden. Per Standard-Konfiguration entsteht so auf jeder Seite, auf der dieses Tag geladen wird, ein Seitenaufruf-Event. Mit aktiver Protokollierung in der Konsole des Browsers (siehe Code) kann man diese nachvollziehen und im Netzwerk-Tab (oder der Vorschau des ssGTM) zeigen sich die Requests, die walker.js versendet.

Beispiel Ereignisse: E-Commerce

Mit Seitenaufrufen allein ist es i. d. R. nicht getan. Während walker.js eine Menge Optionen bietet, um bestimmte Dinge wie Scrolltracking, Sichtbarkeit von Elementen, Klicks etc. durch relativ einfache Konfiguration automatisch in Events verwandeln kann, ist es wie o. a. in einem GTM üblicher, dass es schon Daten im dataLayer und bestehende Trigger gibt, um Event-Tags auszulösen.

Hier sollen daher zwei typische Beispiele gezeigt werden, die in einem E-Commerce-Setup anfallen. Bei einem "add_to_cart" wird dabei das walker.js Event Tag eingesetzt und beim "purchase" ein normales HTML Tag. Denn wie auch bei Meta und anderen Diensten ist es unter bestimmten Bedingungen sinnvoller, mit JavaScript in einem HTML Tag zu arbeiten, statt ein Tag Template zu nutzen, dass dann mit vielen kleinen JavaScript Portionen in Form von JavaScript Variablen gefüttert werden muss. Daher werden hier beide Wege demonstriert.

Hinzufügen zum Warenkorb (Template Beispiel)

Um das Tag Template für das Erstellen eines Events zu verwenden, ist die Vorgehensweise vergleichbar mit anderen Tags: Neues Tag anlegen, "walker.js Event" als Typ auswählen und dann die Eigenschaften in Form von Feldern definieren.

Mindestens sind hier die Angaben zu Entity und Action erforderlich, um ein gültiges elbwalker Event zu erstellen. Das kann "product" und "add" sein - die Eigenschaften (auch der Ereignisname) für GA4 können später separat definiert werden (siehe unten).

walker.js Add To Cart Event

Ein Trigger kann aus einer Liste ausgewählt oder per Variable definiert werden. Die Vorgaben der Liste entsprechen der Dokumentation. Wer ausschließlich GA4 als Ziel im Sinn hat, kann den Trigger mit einer Variable vom Typ "Undefinierter Wert" belegen oder beliebig füllen.

Die "data" und "context" Objekte

Ein walker.js Event hat mehrere Bereiche, in denen weitere Daten untergebracht werden. Das ist z. B. ein "globals" Objekt, in dem alle Daten / Eigenschaften zu finden sind, die alle Ereignisse auf der Seite betreffen. Auf der anderen Seite ist das "data" Objekt mit weiteren Eigenschaften, die das Event selbst betreffen, also z. B. die URL einer Seite bei einem Seitenaufruf oder die Transaktions-ID bei einem "purchase". Dazwischen liegt der "context", dessen Daten z. B. für eine Gruppe von Ereignissen Gültigkeit haben können. Es sei erneut auf die Website verwiesen, wo die Tagging Konzepte und der Aufbau des walker.js Events erläutert werden.

Generell können beide Bereiche auf verschiedene Weise mit Daten belegt - oder leer gelassen - werden. Nicht alle Ereignisse haben weitere Eigenschaften. Wenn Daten angegeben werden sollen, bestehen diese stets aus einer Kombination von einem Namen "Key" und einem Wert "Value". Deren Definition kann als JavaScript Variable erfolgen, die ein Objekt mit den gewünschten Daten enthält oder in Form einer Tabelle direkt beim Event definiert werden (was eher dem Vorgehen bei der Definition von Ereignisparametern bei GA4 Ereignissen entspricht). In beiden Fällen können die Namen entweder beliebig gewählt oder eben an den Anforderungen eines GA4 Ereignisses orientiert werden.

In der Abbildung ist dies z. B. nur der "event_name", um einen passenden Ereignisnamen mitzuliefern, denn sonst wird am Server später ein "product add" ankommen. Das ist nicht tragisch, weil auf der Serverseite eine Übersetzung der Events stattfinden kann, aber es ist vermutlich sowohl einfacher zu warten und zu verstehen, wenn alle Parameter an einer Stelle definiert werden.

Wer den Weg einer Benutzerdefinierten JavaScript Variable gehen möchte, kann sich am, folgenden Code orientieren, wo einige Parameter für ein frei erfundenes Ereignis definiert werden:

function(){
return {
"element_id": "element37",
"element_name": "Some random DOM element",
"is_tag": 22050000,
"eigenschaft_x": {{your variable name here}},
"element_category": "Promo"
};
}

Hinweis: Wer ein möglichst vollständiges Event abliefern will, sollte hier - oder in der Tabelle zur Konfiguration (siehe Abbildung) - die Angaben zu "value" und "currency" hinzufügen. Passende Variablen dazu, die die Angaben aus dem dataLayer lesen, um diese für GA4 Events bereitzustellen, existieren vermutlich schon.

Das "nested" Objekt

Ein walker.js Ereignis beinhaltet einen "nested" Bereich, in dem ein Array mit mehreren - möglicherweise tiefer verschachtelten - Elementen transportiert wird. Dies bietet sich im Kontext von GA4 und E-Commerce natürlich besonders an, um die Produktdaten (im GA4 Jargon "items") zu übergeben. In der Dokumentation findet man weitere Angaben zum Format, das unter anderem aus einem "type" und einem "data" Objekt besteht, in denen wiederum Schlüssel/Wert-Paare enthalten sind.

Es existieren mehrere Optionen zur Belegung des Objekts. Neben dem schon bekannten Weg einer Variable kann das Tag diese direkt aus einem E-Commerce dataLayer für GA4 auslesen ("ecommerce.items"). Das macht die Umstellung unter Beibehaltung des bestehenden dataLayers besonders einfach, denn per Option lassen sich diese "items" dann direkt in das walker.js Format konvertieren. Dabei wird "product" als Typ verwendet, so dass der Client am ssGTM (siehe unten) die Daten aus dem "nested" Array ohne weitere Einstellungen verstehen und wieder zurück verwandeln kann.

Hier sei ein Hinweis erlaubt: Ja, es wäre möglich, die Produkte direkt als "items" im "data" Objekt unterzubringen. Ist zwar nicht vorgesehen, funktioniert jedoch technisch einwandfrei. Dieses Vorgehen ist vollkommen in Ordnung, solange man wirklich nur mit GA4 arbeiten will. Es wäre aber schade, die Formatvorgaben eines walker.js Ereignisses zu ignorieren, denn je nach gewünschter weiterer Verwendung des Events am Server verbaut man sich damit bestehende Wege der Weiterverarbeitung.

Auf diese Weise lassen sich weitere E-Commerce-Ereignisse definieren und "GA4 gerecht" mit Daten bestücken. Als Trigger dienen dann je nach Einsatzzweck die bereits bestehenden Auslöser, welche man schon für GA4 Tags im Einsatz hat, oder es werden neue Trigger erstellt, die unabhängig von Zustimmung immer feuern, das Event an den eigenen Server melden und dort wird die Consent-Lage dann aufgelöst und nur die Dienste bedient, die man bedienen darf. Mehr dazu noch weiter unten im Abschnitt zur Trigger-Gestaltung.

Kaufabschluss (JavaScript Beispiel)

Unter Verwendung des Tags kann - wie oben beschrieben - jedes andere Event definiert und gesendet werden. Möchte oder muss man aber stattdessen auf HTML Tags setzen, um dort flexibler bei der Bestückung der Werte zu sein, ist das machbar. walker.js arbeitet mit einem eigenen dataLayer, der "elbLayer" genannt wird und in den sowohl Befehle, als auch Konfigurationen oder Ereignisse abgelegt werden, die das Script dann verarbeitet. Um ein neues Ereignis auszulösen, müssen die Angaben dazu also in den elbLayer geschrieben werden. Eine Funktion dazu ist im Konfigurations-Tag vordefiniert und heißt dort elb(). Mittels dieser Funktion kann ein Kauf (oder jedes andere Ereignis) genauso in den elbLayer gelangen, wie es mit Hilfe des Event Tags geschieht. Hier ein Beispiel:

<script>
var elb = elb || function () {(window.elbLayer = window.elbLayer || []).push(arguments);}
elb("order success",
{
transaction_id: {{ecommerce.transaction_id}},
tax: {{ecommerce.tax}},
shipping: {{ecommerce.shipping}},
value: {{ecommerce.value}},
currency: {{ecommerce.currency}}
},
"load",
{event_name: "purchase", session_start: false},
{{convert2nested}}({{ecommerce.items}})
);
</script>

Hierbei werden verschiedene Werte wie die Transaktions ID als dataLayer Variablen eingefügt, wie sie auch für ein GA4 purchase Ereignis verwendet würden. Einzig besonders ist hier die Konvertierung der Produkte über eine Funktion "convert2nested", die als Variable angelegt werden muss, damit das Tag diese nutzen kann. Der Code dieser Konvertierungsfunktion, die die Umstellung in das "nested" Format übernimmt (was das walker.js Event Tag mit der o. a. Option genau auf die gleiche Art erledigt):

function() {
return function(eec) {
var src = eec;
if (!eec || typeof(eec) !== "object") return [];
//do we have items / products or a complete ecommerce object?
if (eec.ecommerce && eec.ecommerce.items)
src = eec.ecommerce.items;
else
if (eec.items) src = eec.items;
if (!src || !Array.isArray(src)) return [];
try {
return src.map(function(x){
return {
type: "product",
data: x
}
});
} catch(e) {
return [];
}
}
}

Hinweis: In der Hilfe im Repostory findet sich ein "purchase" Beispiel, das mittels Tag Vorlage statt eines HTML Tags erstellt wird.

Optionen für Trigger und Consent

Eine Sonderstellung haben hier je nach Einsatz die Consent-Daten, welche je nach Einsatz an verschiedenen Stellen zu finden sein werden. Bedient man sich der Consent-Funktionen von walker.js, findet sich bei jedem Event im "consent" Objekt die aktuelle Lage. Wer bereits Consent Informationen auf andere Weise (statt als logische Informationen für einzelne Dienste und Gruppen) im Tag Manager zur Verfügung hat, kann diese wahlweise auch als "globals" Feld(er) hinzufügen und am Server auswerten. Oder es sind vielleicht Consent-Cookie-Werte im Header der Tracking-Requests zu finden. Je nachdem, ob man die Events immer aus dem Browser versendet, um die Consent-Lage dann hier am Server aufzulösen oder ob Events nur bei Zustimmung generiert wurden, sind die server-seitigen Tags also passend zu dem zu triggern, was erlaubt ist. Wahlweise sind die Consent Bedingungen direkt als Event Parameter breitstellbar (siehe oben), so dass man diese dort auslesen und in Triggern nutzen kann, wenn man Ereignisse immer an den eigenen Server sendet; ungeachtet der Consent-Lage.

Part II: Empfang von walker.js Events mit server-side GTM

Nachdem alle Events in der gewünschten Form im Browser entstehen, müssen diese nun auf dem Server entgegengenommen werden, um sie den dortigen Tags zur Verfügung zu stellen. Dazu dient eine eigene Client Vorlage, die am ssGTM installiert wird. Die Template Datei findet sich in einem eigenen Repository und wird auf gleiche Weise wie beim browserseitigen GTM als Vorlage (diesmal als Client) installiert.

Mit der neuen Vorlage kann dann ein Client im Container angelegt werden, der fortan auf walker.js Ereignisse reagieren kann.

Konfiguration des Clients

Bereitstellung von walker.js über den eigenen Server

Neben dem Empfang von Requests mit Ereignissen kann der Client genutzt werden, um das Tracking-Script über den eigenen Endpunkt bereitzustellen. Ähnlich wie bei der Bereitstellung von GTM Container oder gtag.js / analytics.js durch die Google-eigenen Clients wird dabei die gewünschte Version abgerufen und im Cache des Servers gespeichert. Dabei ist ein beliebiger abweichender Name zu definieren, unter dem das Script von Server abrufbar sein soll.

Per Vorgabe "hört" der Client auf den Pfad /elbwalker. Werden die Events aus dem Browser an einen anderen Pfad gesendet (der dort in den Einstellungen des Configuration Tags bzw. der HTML Initialisierung eingegeben wurde), kann der Client entsprechend konfiguriert werden. Sowohl Pfad und Name des Scripts als auch "Empfangskanal" des Clients sind damit frei wählbar.

Session und Client Daten

Die meisten Tags benötigen eine Id auf die eine oder andere Art. Je nachdem, wie diese Daten gesendet werden, können entweder Variablen, Daten aus dem walker.js Ereignis (Vorgabe sind die Attribute des user-Objekts) oder bestimmte Cookie-Werte sein. Eigentlich nur für GA4 relevant ist dabei die Sitzungs-Nummer. Stellt man nichts um, passt das Setup genau zu den Daten aus der Beispiel-Konfiguration aus Part 1.

Ereignisse verarbeiten

Wenn walker.js Ereignisse empfangen werden, stellt der Client alle empfangenen Daten im Event-Modell des Tag Managers zu Verfügung. Dabei werden möglichst alle "Standardparameter" so benannt, wie man es von einem Google Client gewohnt ist und wie es von den meisten Tags auf der anderen Seite erwartet wird. Speziell der Ereignisname ist allerdings i. d. R. nicht "GA4 konform". Während die Events aus den obigen Beispielen stets einen passenden "event_name" über die "globals" beinhalten, kann hier bei Bedarf eine Anpassung der ansonsten aus entity und action zusammengesetzten Ereignisnamen erfolgen.

Weitere Einstellungen zur Verarbeitung finden sich in den "Advanced Settings":

  • Der Standardpfad /elbwalker für den Client kann wahlweise angepasst werden
  • Damit die in "consent", "data", "context" und vor allem den "globals" gesendeten Informationen im Event-Modell landen, dienen die (per Vorgabe aktiven) Optionen zur Übernahme aller dortigen Schlüssel/Wert-Paare. Soll GA4 also z. B. die "session_number" nutzen, die dort untergebracht ist, ist das der einfachste Weg zur Übergabe an die Tags. Alternativ könnten die Daten "manuell" aus dem ebenso vollständig in einem eigenen Key namens "x-elb-event" abgelegten walker.js Ereignis ausgelesen werden (z. B. mit einer "Extract From JSON" Variable), um diese dann bei Tags manuell zuzuweisen und vorher ggf. noch anzupassen.
  • Weitere Parameter können in einer Tabelle hinzugefügt oder vorhandene Werte überschrieben werden.

Generell ist es empfehlenswert, die Option zum Erhalt des eingehenden walker.js Events im Event-Modell aktiviert zu lassen, wenn mehr Empfänger als nur GA4 geplant sind. So können ggf. auch Daten, die sonst keinen eigenen Platz in den Ereignisdaten des GTM finden, bei der Bestückung von Tags genutzt werden. Wie z. B. das Tag zur Weitergabe der Ereignisse an BigQuery (siehe unten).

GA4 Einstellungen und Ziele

Den Abschluss bildet ein Block mit Einstellungen, die nur für GA4 relevant sind. Darunter:

  • Der Pfad zum Sitzungsstart-Marker, der durch die o. a. HTML Konfiguration für walker.js im Browser generiert wird.
  • Konvertierungsoptionen für E-Commerce Items, die hier wieder aus dem "nested" Objekt ausgelesen werden.
  • Da bei Einsatz von gtag.js der Browser weiß, welches Event eine Conversion ist und wir diese Information nicht aus dem Browser senden (wen geht was an, was für einen Betreiber ein Ziel ist oder nicht?), muss diese Information nun am Server generiert werden, damit GA4 Tags die ausgehenden Events entsprechend markieren können. Genauso wie - nur für GA4 - eine angelieferte Session ID und Nummer erforderlich sind.
  • En optionaler Debug Marker für GA4 zur Aktivierung des DebugView (siehe unten)

GA4 Tags konfigurieren

Nachdem mit dem Tag im GTM und dem Client am ssGTM der komplette Weg umgestellt wurde, wie Daten zu GA4 Tags (oder Universal Tags) gelangen, ist die Konfiguration des Tags selbst erfreulich einfach, denn alles soll ja genau so funktionieren, wie es bei gtag.js der Fall wäre.

Lediglich einige zusätzliche Event-Parameter werden durch den elbwalker Client erstellt, die man ggf. in der Konfiguration seiner GA4 Tags ausschließen möchte - wozu die GA4 Tags in der Konfiguration einen eigenen Bereich anbieten. Sinnvoll ist es i. d. Regel, die folgenden Daten nicht an GA4 zu senden, wenn man damit nichts in Form einer Benutzerdefinierten Dimension und / oder in BigQuery anfangen kann:

  • x-elb-event
  • x-elb-walker-version
  • x-elb-config-version

Ergebnisse kontrollieren

Events in ssGTM Vorschau

Als erster Schritt sollte die GTM Vorschau im des Browser GTM und die des ssGTM gemeinsam genutzt werden, um den ordnungsgemäßen Empfang und die Verarbeitung von Ereignissen zu kontrollieren. Der mit Konfiguration und Ereignis Tags versehene GTM sollte das Feuern der Tags zeigen und in der Konsole sollten sich die ausgehenden Requests zum Tagging Server zeigen.

Dort wiederum zeigt die Vorschau, was an Requests ankommt und was damit passiert. Wird der Tagging Server genutzt, um das Script auszuliefern, sieht man einen passenden Request in der Summary - ebenso wie eingehende Tracking-Requests und die daraus erstellten Ereignisse. Feuern Tags wie GA4, Meta Conversions API oder andere, ist eine Kontrolle der ausgehenden Requests und Antworten der Server möglich. Und vor allem ein Blick auf die empfangenen und gemäß der Einstellungen im elbwalker Client verarbeiteten Parameter des Events inkl. des x-elb-event Keys (wenn konfiguriert).

walker.js Event am ssGTM in der Vorschau

Events im Debugger von GA4

Wer im DebugView von GA4 direkt kontrollieren möchte, ob die Daten in der gewünschten Form und mit vollständigen Parametern ankommen, kann beim Client das Setzen des Debug-Flags aktivieren. In diesem Fall wird direkt in GA4 im DebugView zu sehen sein, was über den ssGTM an GA4 weitergeleitet wurde - einschließlich aller Parameter.

walker.js Event im DebugView

Dabei können durchaus irrelevante Daten sein, die dann durch Konfiguration des GA4 Tags am Server zurückgehalten werden können (siehe oben).

Ergebnisse in Reports

Auch in der Echtzeit oder Reports sollte sich alles wiederfinden, was man dort erwarten dürfte... wenn es denn gesendet wurde. Meint: Die Vorlagen auf Github verzichten z. B. darauf, die Dimensionen des Browsers zu erheben. Besteht Zustimmung, kann dies bei der Initialisierung bei Bedarf noch durch Ergänzung der "globals" im Browser geschehen, ohne sich mit dem TTDSG anzulegen. Weitere "Kleinigkeiten" fehlen möglicherweise, die in 99% der Fälle nicht benötigt werden, aber im konkreten Anwendungsfall ggf. relevant sind. Daher ist es eine gute Idee, die neue Struktur ausreichend zu testen, bevor man das bisherige Tagging mit gtag.js aufgibt. Laufen beide Wege eine gewisse Zeit parallel, ist der Vergleich ohne Zeitdruck in den meisten Fällen die beste Idee.

Weitere Nutzung des Datenstroms

Selten wird nur GA4 über einen ssGTM mit Daten bedient. Durch die möglichst große Anlehnung der Datenstruktur im Event-Modell an Google Analytics Ereignisse sollten andere Dienste wie Meta Conversion API, Piwik PRO, Matomo oder andere problemlos mit den Daten arbeiten können. Für Plausibe, Umami und Pirsch Analytics sind bei Bedarf passende Tags am Server zu betreiben. Oder: Daten direkt an eine Datenbank weitergeben.

sGTM BigQuery Tag Template

Für viele ist GA4 hauptsächlich ein Weg, um Daten in BigQuery zu bekommen. Je nachdem, was man damit dann anfangen will, kann man sich den Umweg ggf. sparen und alle Events direkt in eine BQ-Tabelle schreiben. Dazu dient neben anderen in der Community Gallery bereits bestehende BigQuery Tags nun wahlweise das neue "walker.js To BigQuery" Tag Template, welches ebenfalls bei elbwalker auf Github zu finden ist.

Mit dem dort zu findenden JSON Schema kann eine passende Tabelle angelegt und über das Tag Template ohne Umweg mit Daten versorgt werden. Zur Nutzung wie folgt vorgehen:

  1. Template wie gewohnt installieren als neue Tag Vorlage im ssGTM
  2. Neues Tag hinzufügen und dort Projekt ID (bei abweichendem Projekt), eine Datenbank ID und einen Tabellennamen angeben
  3. Eingehende walker.js Ereignisse werden bei automatischem Betrieb aus dem Event-Modell gelesen. Im Client muss dazu die Weitergabe an den x-elb-event Parameter aktiv sein. Anderenfalls kann eine Variable als Eingangswert verwendet werden, wenn z. B. Ereignisse einer anderen Quelle zunächst in ein walker.js Ereignis umgewandelt werden sollen oder eine Anreicherung bzw. Anpassung des Events vor dem Speichern gewünscht ist.
  4. Optional können weitere Daten hinzugefügt werden, die je nach Struktur der Ziel-Tabelle in einem REPEATED RECORD oder als JSON abgelegt werden.

Alle Ereignisse werden vom Tag dann in die Tabelle geschrieben, die eigene JSON Felder für globals, data, context, consent und nested bereitstellt. Eine Beispielabfrage, die verschiedene Methoden zum Zugriff auf die Daten zeigt:

SELECT
timestamp AS event_timestamp,
"page_view" AS event_name,
JSON_VALUE(data.domain) AS page_hostname,
JSON_VALUE(data["title"]) AS page_title,
/* optionally use JSON_EXTRACT instead of dot notation */
JSON_VALUE(JSON_EXTRACT(data, "$.id")) AS page_path,
user.device AS client_id,
user.session AS ga_session_id,
FROM
`your-project.your-database.your-walker_events-table`
WHERE
event = "page view"
LIMIT
100

Das Ergebnis in BigQuery sieht dann in etwa so aus:

walker.js Events im BigQuery

Auf diesem Weg kann man sich - je nach gewünschtem Setup - eine komplette Datenbank aller Events anlegen (solange man sich irgendwie vor Bots schützt ;)), die unabhängig von GA4 funktioniert und - ebenso je nach Setup - mal mehr und mal weniger Dimensionen beinhaltet.

Alternativen zur Alternative?

walker.js ist sicher nicht der einzige Weg, um Daten an einen ssGTM zu senden. Wenn es darum geht, das sehr speziell in seinem Anforderungen gestaltete GA4 mit Daten zu versorgen, sind viele der bestehenden Lösungen problematisch für GA4, weil es an den wesentlichen Merkmalen der Sitzungen fehlt. Eines sticht dabei besonders hervor: Der Start der Sitzung. Gelingt es nicht, die für GA4 so wesentlichen "session_start" und "first_visit" - Marker zu senden, fehlt es in GA4 an allen Ecken und Enden an Attribution. Genau deshalb ist so viel Arbeit investiert worden, mit walker.js ein wirklich unabhängiges Format so auszubauen und zu unterstützen, dass damit eine Alternative zu gtag.js existiert.

Auch andere haben sich dieser Aufgabe gewidmet und sowohl hier auf meinem Blog als auch dem Youtube Kanal und auf Github finden sich z. B. Spuren "meines eigenen" Data Capturings, das auf meiner Website zum Einsatz kommt. Das Format ist sehr auf meine eigenen Bedürfnisse zugeschnitten und auf Zusammenspiel mit "meinem" Endpunkt ausgerichtet.

Mit walker.js ist das anders, denn diese Lösung gab es schon vor dem ssGTM und sie wird sich ohne eigenes Zutun weiterentwickeln. Daher empfehle ich jedem, der sich von gtag.js trennen will, möglichst auf die Entwicklung und Pflege eigener Lösungen zu verzichten - ich habe mit entsprechender Pflege jedenfalls reichlich Zeit verbracht. Wer will das schon?😉

Wenn es schon etwas anderes als gtag.js oder walker.js sein soll, empfiehlt sich vermutlich nach aktuellem Stand vor allem die leichtgewichtige gtag-Alternative GA4MP von David Vallejo. Das Script kümmert sich ebenfalls um die Dinge, die im Browser "erledigt" werden müssen wie das Vermerken eines Sitzungsstarts. Ebenfalls als Open Source Lösung verfügbar, ist eine gewisse Beständigkeit und vor allem Weiterentwicklung gegeben. Anders hingegen ist das Format, in dem Daten versendet werden: Es ist parametergleich mit gtag.js. Damit kann man so wahlweise Daten direkt aus dem Browser an GA4 senden oder im GA4 Format an den eigenen Server, wo ein Standard GA4 Client die Daten verstehen und verarbeiten kann (denn sie sehen aus, wie von gtag.js gesendet).

Diese Methode hat gleichermaßen Vor- und Nachteile, die beide in dieser Parametergleichheit liegen: Am ssGTM gibt es keine Besonderheiten bei der Nutzung von GA4MP, weil alles "wie immer" funktioniert. Dafür ist die Wahrscheinlichkeit, dass Browser jetzt oder künftig Requests aufgrund der Parameter-Zusammenstellung blockieren. Mit den unterschiedlichen Optionen der Übergabe per POST oder GET; wahlweise beides als codierte Nutzlast, ist diese Wahrscheinlichkeit bei Verwendung von walker.js Tags vermutlich deutlich geringer.

Ausblick

Der eigentliche Vorteil beim Einsatz dieser Lösung ist nicht allein die Tatsache, dass man von gtag.js im Browser unabhängig ist und damit einen zuverlässigen und datenschutzfreundlichen eingehenden Datenstrom am Tagging-Server hat, sondern vor allem die ganzen Möglichkeiten, die bei walker.js im Tagging selbst stecken. Als direkt implementierte Lösung inkl. Consent Management ohne Race Conditions im Zusammenspiel mit verschiedenen Destinations kann man damit eigentlich komplett auf den Google Tag Manager im Browser verzichten, wenn die eigenen Tagging Anforderungen entweder nicht zu komplex sind... oder in einem Relaunch so mitgedacht wurden, dass die interessante Alternative über die data-elb-Attribute zum Einsatz kommen kann.

Mit der Version 1.6.0 hat walker.js einen recht umfangreichen Ausbau erfahren. Damit wird aber die Reise bestimmt nicht enden. Eine Bibliothek mit viel Kontrolle beim Einsatz, die sich weiterentwickelt, ohne dass man selbst dazu beitragen muss, ist sicherlich ein Vorteil. Und bei der Richtung, in der sich gtag.js als Alleskönner mit geringer Kontrolle über die Datenerhebung entwickelt, mag dieser Punkt immer relevanter werden. Speziell in Zeiten, in denen der Datenschutz die Regeln laufend neu zu schreiben scheint.

Hat Dir der Beitrag geholfen?

Dann freue ich mich, wenn Du ihn mit anderen teilst! Wenn Du magst, gib einen aus ;)

© 2001 - 2024 Markus Baersch