Tutorial: E-Commerce-Analytics von Client-Side auf Server-Side GTM migrieren

Inhalt
- Schritt 1: Beides laufen lassen, später umschalten
- Schritt 2: Den Tagging-Server bereitstellen
- Schritt 3: Der GA4-Client
- Schritt 4: Den Web-Container auf den Server richten
- Schritt 5: Den Kauf aus dem Browser holen
- Schritt 6: Vergleichen, bevor etwas abgeschaltet wird
- Innerhalb der Leitplanken bleiben
- Fragen und Antworten
- Quellen
- Praxiskontrolle: Bestellungen mit dem Shop-Export abgleichen
- Die Analytics-CSV mit BigQuery vorbereiten
Jeder Shop mit clientseitigem Tracking meldet weniger Käufe, als er abwickelt. Diese Lücke ist kein aufzuspürender Fehler: Anfragen an bekannte Analytics-Hostnamen stehen auf Filterlisten, der Tracking-Schutz verkürzt die Lebensdauer des identifizierenden Cookies, und wer den Tab schließt, bevor die Bestätigungsseite fertig gerendert ist, sendet das Event gar nicht erst. Ein serverseitiger Container ändert, wohin die Daten laufen, und deckt damit einen Teil davon ab – das Kauf-Event aus dem Browser zu holen deckt den Rest ab.
Die folgende Anleitung behandelt das als Migration und nicht als Neubau: Das bestehende clientseitige Setup bleibt durchgehend aktiv, beide laufen lange genug parallel, um verglichen zu werden, und umgeschaltet wird erst, wenn die Zahlen es rechtfertigen.

Schritt 1: Beides laufen lassen, später umschalten
Die sicherste Reihenfolge sendet Daten an den Server-Container, während das clientseitige Setup weiter in dieselbe oder eine parallele Property meldet. Nichts wird gelöscht, keine Tags werden pausiert, und der Vergleich läuft auf echtem Traffic statt im Vorschaumodus.
Eine zweite GA4-Property als Migrationsziel hält die Produktionszahlen während der Überlappung sauber – ein doppelter Datenbestand in der Live-Property ist hinterher schwerer zu entwirren, als eine temporäre zweite Property wegzuwerfen ist. Zwei bis vier Wochen Überlappung decken Wochentags- und Wochenendmuster sowie mindestens einen vollständigen Kaufzyklus ab.
Schritt 2: Den Tagging-Server bereitstellen
In der GTM-Oberfläche entsteht ein Server-Container als eigener Containertyp, und seine Einstellungen bieten die automatische Bereitstellung in Google Cloud Run an. Der automatische Weg ist bequem und erzeugt ein funktionierendes Deployment; eine manuelle Bereitstellung desselben öffentlichen Images gibt mehr Kontrolle über Region und Skalierung:
gcloud run deploy sgtm \
--image=gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable \
--region=europe-central2 \
--platform=managed \
--allow-unauthenticated \
--set-env-vars=CONTAINER_CONFIG='<Config-String aus den Containereinstellungen>'
Die voreingestellten Werte sind auf Tests und nicht auf Produktionsvolumen ausgelegt; die Instanz- und Speicher-Flags sind der Teil, den es bei echtem Volumen erneut anzusehen lohnt. Jede Container-Laufzeitumgebung funktioniert gleichermaßen – Cloud Run ist der dokumentierte Standard, keine Voraussetzung.
Nicht optional ist der Hostname. Ein Tagging-Server, der nur unter seiner generierten Cloud-Adresse erreichbar ist, ist ein Drittanbieter-Host wie jeder andere; der Vorteil des First-Party-Kontexts entsteht erst, wenn er auf einer Subdomain der eigenen Shop-Domain antwortet, etwa sgtm.shop.example.com, mit passendem DNS-Eintrag und zugeordnetem Zertifikat.
Schritt 3: Der GA4-Client
Ein Server-Container tut nichts, solange kein Client die eingehenden Anfragen annimmt. Der eingebaute GA4-Client lauscht auf den Pfaden, die ein Google-Tag verwendet, zerlegt den eingehenden Hit und macht daraus ein Event, das serverseitige Tags lesen können – ohne ihn nimmt der Container Anfragen entgegen und verwirft sie.
Zwei Einstellungen verdienen eine Entscheidung statt einer Voreinstellung. Der Client kann die Ausgabe des identifizierenden Cookies übernehmen, statt sie JavaScript zu überlassen – das ist es, was das Cookie gegenüber Browser-Beschränkungen dauerhaft macht. Ihn ohne die zugehörige Migrationsoption einzuschalten setzt die Identität jedes wiederkehrenden Besuchers zurück; das gehört daher in eine eigene Änderung mit eigener Prüfung. Die zweite betrifft die Pfade: Die Standardpfade unverändert zu lassen ist das, was dem Web-Container erlaubt, Hits ohne eigene Endpunkt-Konfiguration zu senden.
Schritt 4: Den Web-Container auf den Server richten
Auf Browserseite leitet ein einziges Feld den Verkehr um. In einem Google-Tag im Web-Container wird die Server-Container-URL als Konfigurationsparameter gesetzt; in einer reinen gtag.js-Implementierung ist das Gegenstück transport_url:
// Konfigurationsparameter im Google-Tag (Web-Container)
server_container_url: 'https://sgtm.shop.example.com'
// Entsprechung in einer reinen gtag.js-Implementierung
gtag('config', 'G-XXXXXXXXXX', {
server_container_url: 'https://sgtm.shop.example.com'
});
Ab diesem Punkt adressiert der Browser die eigene Subdomain des Shops, und der Server-Container leitet an GA4 weiter. Der Server-Container hat einen eigenen Vorschaumodus, der die eingehende Anfrage zeigt, den Client, der sie angenommen hat, und jedes daraus ausgelöste Tag – die Stelle, an der ein falsch geleiteter Hit sofort sichtbar wird statt einen Tag später im Bericht.
Schritt 5: Den Kauf aus dem Browser holen
Die Leitung über eine eigene Subdomain verringert das Blockieren; sie beendet es nicht, und gegen den Besucher, der die Bestätigungsseite nie erreicht, hilft sie gar nicht. Erst ein Event, das das Backend nach der Bestellbestätigung im Shopsystem sendet, ist vollständig unabhängig vom Browser.
Diese Anfrage braucht die Kennungen, die im Browser liegen. Die Client-ID aus dem Analytics-Cookie muss im Checkout ausgelesen und zusammen mit der Sitzungs-ID am Auftrag gespeichert werden, sonst kommt der Kauf ohne zugehörige Sitzung an und landet im Bericht als Traffic ohne Quelle:
POST https://sgtm.shop.example.com/g/collect
v=2
&tid=G-XXXXXXXXXX
&cid=1234567890.1690000000 // im Checkout aus dem Analytics-Cookie gelesen
&sid=1789000000 // die Sitzungs-ID desselben Besuchs
&en=purchase
&ep.transaction_id=ORD-10432
&epn.value=149.00
&ep.currency=PLN
Wird derselbe Kauf sowohl aus dem Browser als auch aus dem Backend gesendet, muss die Transaktionskennung übereinstimmen, damit sich das Duplikat nachgelagert erkennen und entfernen lässt – die Alternative ist ein Shop, dessen Umsatzzahlen genau um die Events aufgebläht sind, die die Migration zurückholen sollte.
Schritt 6: Vergleichen, bevor etwas abgeschaltet wird
Der Vergleich, der über die Umschaltung entscheidet, lautet nicht clientseitig gegen serverseitig, sondern beide jeweils gegen die Bestellanzahl des Shops. Ein serverseitiges Setup, das mehr Käufe meldet als zuvor, ist nur dann eine Verbesserung, wenn die zusätzlichen Käufe echten Bestellungen entsprechen – und die Bestelltabelle ist die Referenz, die das klärt.
Typische Befunde während der Überlappung: Die Kaufzahlen steigen um eine Spanne, die stark von Publikum und Gerätemix abhängt, Sitzungen gewinnen an Dauer, weil das identifizierende Cookie länger überlebt, und einige Tags erweisen sich als abhängig von Browser-Variablen, die der Server-Container nicht hat. Diese Tags sind die eigentliche Migrationsarbeit; der Container selbst ist der leichte Teil.
Innerhalb der Leitplanken bleiben
Ein serverseitiger Container verlagert die Verarbeitung, nicht die Pflicht. Der Consent-Status muss mit der Anfrage reisen und ausgewertet werden, bevor irgendein Tag auslöst, und er muss am Auftrag gespeichert sein, damit auch das Backend-Event ihn prüfen kann – eine vom Server gesendete Anfrage ist nicht befreit, weil der Browser nicht mehr beteiligt ist. Der Container wird außerdem zu einem System mit laufenden Kosten und einer Verfügbarkeit, von der das Reporting nun abhängt, und das von ihm ausgegebene identifizierende Cookie bleibt personenbezogenes Datum nach denselben Regeln wie zuvor, nur von anderer Stelle gesetzt.
Fragen und Antworten
Muss der Tagging-Server nach jeder Veröffentlichung des Server-Containers neu bereitgestellt werden?
Nein. Der Config-String in CONTAINER_CONFIG bindet den Dienst an den Container, nicht an eine bestimmte Version, und der Tagging-Server lädt die jeweils veröffentlichte Version selbst. Neu bereitgestellt wird nur, wenn ein neueres Image laufen soll: Cloud Run löst gtm-cloud-image:stable beim Bereitstellen auf eine feste Image-Fassung auf, und eine neuere geht erst mit dem nächsten gcloud run deploy in Betrieb.
Was braucht der Vorschaumodus des Server-Containers bei einer manuellen Bereitstellung?
Einen eigenen Dienst. Bei der manuellen Bereitstellung entsteht zuerst ein Vorschau-Server aus demselben Image, mit RUN_AS_PREVIEW_SERVER=true und höchstens einer Instanz, danach der Tagging-Server, dem PREVIEW_SERVER_URL die Adresse dieses Vorschau-Servers mitteilt. Beide erhalten dieselbe CONTAINER_CONFIG.
Der Befehl im Artikel legt nur den Tagging-Server an. Er nimmt Anfragen an, doch die Vorschau, in der ein falsch geleiteter Hit laut Artikel sofort sichtbar wird, hat keinen Ort, an dem sie läuft. Die automatische Bereitstellung legt beide Dienste selbst an; wer den manuellen Weg wählt, übernimmt diesen Teil.
Reicht die eigene Subdomain, damit Safari das vom Server-Container gesetzte Cookie nicht kürzt?
Nicht in jedem Fall. Safari prüft bei Cookies aus einem Set-Cookie-Header auch, wohin eine Subdomain tatsächlich zeigt. Ist sie per CNAME auf einen fremden Host gelegt, wie es bei der Zuordnung einer eigenen Domain zu Cloud Run üblich ist, oder antwortet sie unter einer IP-Adresse, die nicht zum Adressbereich der Website gehört, begrenzt Safari auch diese Cookies auf sieben Tage.
Die Subdomain bleibt trotzdem die Voraussetzung, die der Artikel nennt: Ohne sie gibt es gar keinen First-Party-Kontext. Für die volle Laufzeit in Safari muss der Tagging-Server aber über dieselbe Infrastruktur erreichbar sein wie der Shop, etwa über einen Pfad auf der Shop-Domain, den ein Load Balancer oder CDN an den Server-Container weiterreicht.
Praxiskontrolle: Bestellungen mit dem Shop-Export abgleichen
Das Werkzeug Shop-Umsatz und GA4 abgleichen vergleicht zwei CSV-Dateien lokal. Die Bestell-ID bildet den gemeinsamen Schlüssel. Persönliche Kundendaten sind nicht nötig: Bestell-ID, Betrag und Währung genügen.
- Beide Exporte für denselben Zeitraum und dieselbe Zeitzone vorbereiten. Steuern, Versand und Erstattungen müssen gleich behandelt werden. Artikelpositionen und Erstattungen vorab zu einem vereinbarten Betrag je Bestellung zusammenfassen.
- Trennzeichen und Dezimalzeichen je Datei wählen, Datei laden und die Spalten für Bestell-ID, Betrag und Währung zuordnen. Kennungen mit führenden Nullen bleiben Text.
- Nachkommastellen und eine ausdrückliche Toleranz je Bestellung wählen. Es findet keine Währungsumrechnung statt.
- Die getrennten Gruppen prüfen: auf einer Seite fehlend, doppelte ID, andere Währung und Betrag außerhalb der Toleranz.
- Ergebnis exportieren und einzelne Bestellungen in den Quellsystemen untersuchen.
Doppelte IDs werden markiert statt addiert: Ein mehrfach gesendetes Kaufereignis, ein Export auf Artikelebene und eine Erstattungszeile erfordern unterschiedliche Deutungen. Negative Beträge werden als Zahlen akzeptiert; die fachliche Definition muss dennoch zwischen den Dateien übereinstimmen. Eine fehlende Analytics-Bestellung kann mit Einwilligung, Zeitpunkt, Filtern oder Erfassungsfehlern zusammenhängen und beweist allein keinen defekten Tag. Auch eine Differenz von null belegt nicht, dass alle Bestellungen exportiert wurden. Das Werkzeug addiert keine Gesamtsummen über unterschiedliche Währungen.
Maßgeblich sind der gewählte Export und die GA4-E-Commerce-Dokumentation. Das Data-API-Schema unterscheidet Transaktions-IDs und Umsatzkennzahlen; eine allgemeine Gesamtumsatzspalte ist nicht automatisch mit dem Bestellbetrag eines Shops gleichzusetzen.
Die Analytics-CSV mit BigQuery vorbereiten
Der Exporthelfer im Umsatzabgleich erzeugt eine Kaufabfrage für einen vorhandenen täglichen GA4-Export. Projekt, Datensatz, Zeitraum und Rundungspräzision werden lokal eingegeben. Die Seite führt das SQL nicht aus und fordert keinen BigQuery-Zugriff an.
Die Ergebnisspalten transaction_id, amount und currency passen zu den Vergleichsfeldern. Jeder erfasste Kauf bleibt eine Zeile. Eine zusätzliche Kaufereignis-Anzahl hilft beim Erkennen wiederholter Bestell-IDs; diese werden weder still addiert noch entfernt. Fehlende Beträge werden nicht durch null ersetzt.
- Vor dem Shop-Export die Definition des Kaufbetrags und die Tagesgrenzen abstimmen. Diese Abfrage schließt Erstattungen aus und addiert Steuer oder Versand nicht separat.
- SQL erzeugen, in BigQuery validieren und die Kostenschätzung ansehen. Vor der Ausführung eine Obergrenze für abrechenbare Bytes festlegen.
- Das vollständige Ergebnis als lokale CSV speichern. Im Vergleich Komma als Feldtrenner, Dezimalpunkt und dieselben Nachkommastellen wie in der Abfrage wählen.
- Wiederholte IDs und fehlende Felder vor der Interpretation von Betragsabweichungen untersuchen. Der Vergleich akzeptiert bis zu 20.000 Datenzeilen je Datei. Kennungen in Tabellenprogrammen als Text behandeln.
Zwei herunterladbare, erfundene CSV-Dateien ermöglichen einen nachvollziehbaren Einstieg mit je einem Fall in allen sechs Ergebnisgruppen. Sie sind unabhängig vom SQL und verwenden zwei Nachkommastellen bei null Toleranz.
Quellen: GA4-Exportschema, Abfrageprüfung und Kostenkontrolle sowie Abfrageergebnisse als CSV speichern.