Warum Tracking-Debugging per Network-Tab nicht mehr ausreicht
"Sauberes Tagging" ist das Fokusthema meiner täglichen Arbeit. Marketing-Tags sollen feuern, wenn sie dürfen... und sie sollen es nicht, wenn die Zustimmung fehlt. Im Bedarfsfall ist noch der von mir wenig geliebte Advanced Consent Mode im Spiel, Enhanced Conversions, Deduplikation bei hybriden Setups. Zur Kontrolle gehört meistens auch, sich mit den ausgehenden Daten des Browsers zu befassen. Denn: Nur weil ein Tag angeblich gefeuert hat, müssen die Daten nicht genau so wie gewünscht den Browser verlassen haben. Dazu gab es immer schon zwei Wege: Google Tag Assistant für die Google Welt und eine Armee von "Pixel Helper" Extensions für alles andere auf der einen Seite... oder die Kontrolle des Netzwerkverkehrs in den Entwicklertools des Browsers. Leider wird der letztgenannte Weg aber laufend unzuverlässiger: Google Tag Gateway, Bereitstellung über eigene Pfade am server-side GTM oder Custom Loader von Diensten wie Stape, Taggrs und anderen Anbietern machen die Erkennung der Requests - und das Lesen der Parameter - zunehmend schwieriger. Hinzu kommt, dass der eine oder andere Request dort gar nicht auftaucht, weil ein Service Worker den Versand übernimmt. Was tun?
Requests im Browser "nachweisen"
Über viele Jahre habe ich mich daran gewöhnt, die typischen Requests von Google Analytics, Google Ads, Microsoft Ads, Meta und anderen anhand der Domains zu erkennen, so dass ich diese gezielt im Netzwerk-Tab filtern und bei Bedarf auch die wesentlichen Parameter finden und lesen konnte. Neben einer Kontrolle der ankommenden Daten im Zielsystem wie
- GA4 DebugView
- Echtzeitberichte
- Tracker-Debugger
- Meta Events-Manager u. Ä.
war das für mich stets der beste Nachweis, dass das Tracking so funktioniert, wie es soll.
Da vor allem moderne Pixel mehr übertragen als nur den Seitenaufruf beim Laden des Scripts, war mir ein "Auslösecheck" im Tag Manager stets zu wenig. Wie sehen die automatisch gesammelten Ereignisse von GA4 genau aus? Was genau nimmt das Meta Pixel so alles mit bei jedem Klick? Dafür war der Network-Tab immer eine gute Anlaufstelle.
100 Pixel-Helper?
Mit steigender Komplexität von Tracking-Setups wird das "Parsing" durch reines Lesen von Parametern irgendwann zur Qual. Die Fragen werden zudem komplexer:
- Welche Produkte sind mit dem Add To Cart wirklich an GA4, Meta, Pinterest & Co gegangen?
- Haben wir nun wirklich eine Mailadresse angehängt oder nicht? Senden wir wirklich nur einen Hash oder Klartext?
- Hat der Consent Mode korrekt gegriffen und stimmen die Parameter zur Zustimmung bei den Requests überein mit der Auswahl in der CMP?
- Und hat das auch bei anderen Tools bei Clarity und dem UET Tag von MS Ads genau so funktioniert?
Meine Lösung dafür war eine ganze Zeit ein Konglomerat aus verschiedensten Tools im Browser, die alle vom jeweiligen Hersteller stammten. "Pixel Helper" oder "Tag Helper" gibt es fast von jedem Anbieter, der auch Tracking-Scripts im Browser verbaut sehen will. Eben aus genau dem genannten Grund: Nur im Netzwerk-Tab zu checken, ist mühselig, fehleranfällig und wenig anwenderfreundlich. Auch generalistische Extensions, die den Datenfluss von mehreren Tools sichtbar machen, habe ich dabei eine ganze Zeit verwendet - und einige habe ich auch heute noch im Einsatz.
Wenn sich Tracking weg vom Standard bewegt
Wer sich in diesem Kontext vor allem mit First-Party-Setups via server-side Google Tag Manager und dem Google Tag Gateway auseinandersetzt, wird (wie ich) dabei vermutlich Lücken festgestellt haben. Nicht jedes Setup scheint vollständig mit den o. a. Mitteln zu beobachten sein. Nichts scheint im Network aufzutreten, aber dennoch zeigen sich die Ereignisse im Zielsystem. Beispiele:
- Ein Klick auf den Warenkorb-Button löst sichtbar das add_to_cart Ereignis im Tag Manager aus, im DebugView von GA4 und der Echtzeit ist das Ereignis auch sichtbar. Es hat nur nie erkennbar (per Network und / oder Debugging-Extensions) den Browser verlassen. In diesem Fall war vermutlich ein Service Worker im Einsatz, dessen Request nicht im Netzwerkverkehr der gerade besuchten Seite zu finden ist.
- Man sucht vergeblich nach den altbekannten Requests, die dem Muster "collect?v=2" entsprechen.... oder findet nur LinkedIn, aber nichts, was nach GA4 aussieht. Man findet ggf. noch nicht einmal den Ladevorgang des GTM Containers durch Suche nach der ID "GTM-xxxxx" oder das Laden eines Google-Tags für "G-xxxxx" oder "AW-xxxxxxx". Der wahrscheinlichste Grund ist ein Custom Loader eines sGTM-Hosters wie z. B. Stape. Hierbei wird sowohl der Pfad angepasst, über den die entsprechenden Scripts wie GTM und Google-Tags geladen werden, als auch der ausgehende Request verändert, um die typischen Muster aufzubrechen, an denen Ad Blocker häufig Tracking erkennen und unterbinden.
Beides kommt in der Praxis verstärkt zum Einsatz. Sowohl die Verwendung von Service Workern als auch Tracking-Scripts, die nicht auf die übliche Weise geladen werden und / oder ihre Daten versenden sind längst keine Exoten mehr. Das Microsoft UET Tag sendet z. B. ein "pageHide" Event beim Verlassen einer Seite, welches mal im Network Tab faktisch nie zu sehen bekommt.
Service Worker Requests
Auch GA4 sendet bestimmte Aktionen gern per Service Worker, wenn diese Option im Browser verfügbar ist und Events z. B. dann entstehen, wenn eine Seite gerade gewechselt wird. Das sind z. B. add_to_cart Events, das noch schnell zu versendende user_engagement... aber manchmal auch einfach "Ganz normale" Ereignisse, die dennoch im normalen Netzwerk fehlen und nur durch Inspektion der Aktivität aller derzeit aktiven Service Worker aufgedeckt werden können. Was sehr mühselig ist. Hier ein Beispiel solcher Requests, eingefangen wiederum durch eine dazu eigens erstellte Extension (dazu gleich mehr).

Custom Loader
Der Hauptzweck von Custom Loadern ist es, die Erkennung des Ladevorgangs von Trackingscripts und / oder den Versand von Tracking-Requests vor Blockern abzusichern. Da muss man sich nichts vormachen. Laden vom "eigenen Server" wie einem ssGTM auf einer Subdomain und Versand an diesen sind schon lange nicht mehr ausreichend - und das Spiel wird auch nie aufhören. Solange man sich beim Tracking an die Zustimmungslage hält, ist der Wunsch für mich auch absolut nachvollziehbar, dass der Browser den zugestimmten Trackern keine weiteren Steine in den Weg legen soll.
Deshalb bieten sGTM-Hoster oft angepasste Mechanismen an, um z. B. den Tag Manager zu laden und GA4 Requests an den eigenen Server zu senden. Der Ansatz: Der GTM wird von einem modifizierten Pfad geladen; alle darin verbauten Google-Tags ebenfalls. Die Scripts selbst werden idealerweise so angepasst, dass auch ausgehende Requests nicht mehr dem Standard entsprechen. Dabei wird also z. B. aus einem typischen Request zum Laden des Google Tag Managers...
https://www.googletagmanager.com/gtm.js?id=GTM-ABCDEFG
... etwas sehr generisches wie dieser Pfad hier:
https://stp.beispieldomain.de/ihrrrnjet.js?18=HQFXKSY%2FXyVHPVggNkZUHklXRF9UFhxVFREFAxkAEw4AEg8cGRdAXFoBDw%3D%3D
So werden gängige Muster von Blockern nicht bedient (solange die Domain stp.beispieldomain.de nicht selbst bereits auf einer Blocker-Liste steht) und der Container kann geladen werden. Auf ähnliche Weise werden dann auch die Google-Tags für GA4 oder Google Ads geladen, ohne dass man direkt erkennt, welchem Zweck der Request dient.
Ausgehende Requests verhalten sich genau so. Ein "normaler" Seitenaufruf sieht in etwa so aus, wenn er den Browser verlässt:
https://region1.analytics.google.com/g/collect?v=2&tid=G-ABCDEFG&...&gcs=G111&gcd=13r3r3r2r5l1&...&en=page_view...
Neben dem Standard-Endpunkt, der erkennbaren Measurement-ID des Ziels, zahlreichen (hier gekürzten) Parametern zu URL, Titel, Consent Mode etc. findet man auch den Ereignisnamen im Klartext darin. Mit einem Custom Loader kann der gleiche Request aber auch so aussehen:
https://stp.beispiedomain.de/kgchkqkts?0355ae1a=L2cvY29sbGVjdD92PTImdGlkPUctV1pQU1Q2...
Im Fall von Stape wird hier z. B. der Payload base64 codiert. Man kann den Parameter zwar in die Zwischenablage kopieren und z. B. in der Konsole des Browsers dann mittels atob() umwanden, um wieder einen lesbaren String wie /g/collect?v=2&tid=G-ABCDEFG... zu erhalten, aber das ist natürlich sehr mühselig. Bei Taggs geht man einen Schritt weiter: in den modifizierten Scripts, die über den Custom Loader bezogen werden, steckt ein Key, mit dessen Hilfe im Client alle Requests tatsächlich mittels AES verschlüsselt werden, so dass kein einfaches "Auslesen" mehr möglich ist. Solchen Requests im Browser auf die Parameter zu schauen, macht keine Freude.
Debugging mit der Tracking Auditor Chrome Extension
Aus diesem Grund habe ich mir eine Erweiterung für Chrome gebaut, die das Debugging in solchen Fällen erleichtert. Die Erkennung von Requests ist dabei freilich nur so gut wie meine Tests anhand realer Websites dies zulassen, aber zumindest mit Service-Workern, Google Tag Gateways, First-Party Setups über sGTM mit und ohne Custom Loader von Stape oder Taggrs kommt die Extension nun gut zurecht und macht wieder sicht- und lesbar, was sonst viel Mühe Zeit und reichlich Klicks kostet.
Wird der Einsatz von Service Workern durch die Extension entdeckt, wird ein entsprechender Hinweis als separate Karte ausgegeben. In den Einstellungen kann das Debugging von Workern (da es zusätzliche Berechtigungen erfordert) explizit eingeschaltet werden. Welche Dienste aufgezeichnet und / oder im "Stream" dargestellt werden sollen, kann frei konfiguriert werden.

Ist diese Option aktiv, werden per Worker versendete Requests wie im oben gezeigten Screenshot in den "Stream" von Tracking-Events übernommen. Ist die inaktiv, weist zumindest die Karte darauf hin, dass hier ggf. Requests fehlen.
Nicht nur Google Analytics
Wenn man sich einmal die Mühe gemacht hat, eine separate Extension für Google Analytics Requests zu bauen, die in anderen Tools ggf. untergehen, ist der Gedanke nicht fern, auch die ganzen Pixel Helper zu ersetzen, die beim Check eines typischen Tracking-Setups benötigt werden. Die Idee ist hier, alles in einen gemeinsamen und leicht zu filternden "Stream" aus Tracking-relevanten Requests zu machen. Alle werden bei laufender Aufzeichnung (neue zuerst) nebst Ziel-Dienst, Zeitstempel und Detailinfos zum Inhalt des Requests als Karten dargestellt.
Daher unterstützt der Tracking Auditor die anhand der Pills im Screenshop erkennbar ein- und ausschaltbaren Dienste. Das sind derzeit:
- Google Analytics
- Google Ads
- Floodlight (ab v1.0.0 - derzeit in Review)
- Meta
- Bing / MS Ads
- TikTok
- Snapchat
- Hubspot
- Criteo (v1.0.0)
- Taboola (v1.0.0)
- Outbrain (v1.0.0)
- Awin (v1.0.0)
Wer hier X/Twitter vermisst: Nimm den Pixel Helper, wenn Du wirklich meinst, dieses Ding verbauen und debuggen zu müssen oder schlag Dich mit dem Network-Tab rum, wenn Du willst. Für alle genannten Dienste hingegen gilt: Jeder gefundene Request eines aktiv vermessenen Dienstes kann im Detail im eigenen DevTools-Tab Tracking Auditor untersucht werden, so dass Consent, Produktdaten, PII, Custom Parameter etc. möglichst schnell erfasst und kontrolliert werden können, ohne zwischen Tools oder Tabs wechseln zu müssen. Zumindest ich finde das nützlich und ich nutze die Extension seit ihrer Entstehung tatsächlich jeden Tag.
Wer in einer ähnlichen Situation steckt, wird dieses Werkzeug ggf. ebenso zu schätzen wissen - sei es als Ersatz oder Ergänzung. Ich habe die Extension daher frei verfügbar veröffentlicht. Aktuell ist die Schlagzahl der Updates noch relativ hoch, weil ich laufend neue Sonderfälle finde, die in der Extension abgedeckt werden sollen, so dass der Umfang stetig wächst.
Installation und Nutzung
Die Extension ist im Chrome Web Store kostenlos verfügbar. Weitere Infos, Screenshots und Links zum Web Store und öffentlichen Repository (Vorschläge sind dort jederzeit willkommen!) habe ich hier auf einer eigenen Info-Seite zur Tracking-Auditor Extension zusammengetragen. Es wird sicherlich noch der eine oder andere Dienst dazukommen mit der Zeit. Das Tool wird an seinen - oder besser: meinen - Aufgaben der kommenden Monate mitwachsen.