gtag(‘set’) in der Praxis: eine User ID an ein bereits geladenes Google Tag übergeben
Inhalt
Eine Webanwendung mit Anmeldung erfährt in der Regel einen Moment zu spät, wer die besuchende Person ist. Die Seite lädt, das Google Tag initialisiert sich, der config-Befehl sendet seinen page_view — und erst danach liefert das Login-Formular eine Session zurück oder die Single-Page-Application ermittelt das Konto über einen API-Aufruf. Wenn die User ID existiert, hat der erste Hit den Browser bereits verlassen.
Der Reflex in dieser Lage besteht darin, das Tag ein zweites Mal zu konfigurieren, diesmal mit angehängter Kennung. Dieser Reflex ist teuer und unnötig. Ein bereits geladenes Google Tag muss nicht neu geladen oder neu initialisiert werden, nur weil ein Wert verspätet eintrifft: Ein einzelner set-Befehl übergibt den Wert, und jedes danach auf dieser Seite gesendete Event trägt ihn.

Die fünf gtag-Befehle und wie ihre Geltungsbereiche zusammenwirken
Die gtag.js-API kennt genau fünf Befehle, und ihre Arbeitsteilung ist es, die die späte Übergabe möglich macht.
| Befehl | Signatur | Zweck | Reichweite |
|---|---|---|---|
config |
gtag('config', '<TARGET_ID>', {…}) |
Ergänzt Konfigurationsinformationen für ein Ziel; die TARGET_ID entscheidet, wohin gtag.js Ereignisdaten sendet, ein weiterer Aufruf ergänzt ein weiteres Ziel. | Alle Events an diese eine TARGET_ID. |
set |
gtag('set', {…}) |
Definiert Parameter, die jedem nachfolgenden Event auf der Seite zugeordnet werden. Es existiert auch eine benannte Gruppenform, etwa gtag('set', 'campaign', {…}). |
Global, ab dem Aufruf, nur für die aktuelle Seite. |
event |
gtag('event', '<event_name>', {…}) |
Sendet Ereignisdaten, entweder ein empfohlenes Event oder ein eigenes. | Dieses eine Event. |
get |
gtag('get', '<target>', '<field>', callback) |
Liest Werte aus gtag.js zurück, darunter mit set zugewiesene Werte: client_id, session_id, session_number, gclid. |
Lesezugriff; der Callback erhält das Feld oder undefined. |
consent |
gtag('consent', 'default'|'update', {…}) |
Setzt den initialen Consent-Zustand oder aktualisiert ihn, sobald eine Entscheidung vorliegt. | Consent-Signale für die Seite. |
Es existieren damit drei Geltungsbereiche: einzelne Events, alle Events an eine bestimmte TARGET_ID und global alle Events. Wird derselbe Parameter in mehreren davon zugewiesen, kommt bei der Verarbeitung eines Events nur ein einziger Wert zum Tragen, und die Reihenfolge lautet Event vor config vor set. Das entscheidende Detail steht eine Zeile weiter unten in der Referenz: Vorrang ist kein Überschreiben.
Parameter values set in one scope don’t modify the values set for the same parameter in a different scope.
Im dokumentierten Beispiel wird campaign_id global als '1234' und anschließend in einem config-Aufruf als 'ABCD' zugewiesen; danach lautet der globale Wert weiterhin '1234'. Die Geltungsbereiche halten ihre Werte nebeneinander, und die Rangfolge entscheidet erst zum Verarbeitungszeitpunkt, welcher gilt. Aus der Kombination beider Regeln folgt eine Konsequenz, die die Dokumentation nicht ausformuliert: Ein nach config abgesetzter set-Aufruf verdrängt keinen Wert, den config für dieses Ziel bereits belegt, und wirkt für die Parameter, die config unberührt gelassen hat.
Zur Wiederholung äußert sich die Dokumentation eindeutig: config ist einmal pro Google Tag aufzurufen, jeder weitere Aufruf sollte set verwenden. Die Dokumentation empfiehlt außerdem, wo möglich config oder event gegenüber set vorzuziehen, was insbesondere eigene Event-Parameter betrifft, weil set sie möglicherweise nicht zuverlässig an alle Google-Analytics-Datenströme weitergibt. Für dokumentierte globale Parameter wie user_id, page_title oder currency ist set das vorgesehene Instrument.
Der Fall im Detail: die User ID verspätet übergeben
User IDs sind selbst vergebene Kennungen für einzelne Nutzer; sie konsistent zu vergeben, ist Sache des Betreibers, üblicherweise beim Login. Ist die Kennung schon zum Rendering-Zeitpunkt bekannt, kann sie im config-Aufruf mitreisen. Wird sie erst nach dem Laden der Seite bekannt, ist gtag('set') der dokumentierte Weg. Das Snippet auf der Seite bleibt genau so, wie es installiert wurde.
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
Sobald die Login-Antwort eintrifft, genügt ein Befehl. Kein zweites config, kein zweites Snippet, kein Reload.
fetch('/api/session')
.then(function (response) { return response.json(); })
.then(function (session) {
if (session.analyticsId) {
gtag('set', { 'user_id': session.analyticsId });
}
gtag('event', 'login', { 'method': 'password' });
});
Was danach geschieht, teilt sich zwischen Browser und Verarbeitungsseite auf. Im Browser setzt die Wirkung im Moment des Aufrufs ein und reicht bis zum Ende der Seite. Jedes nach dem set-Befehl abgesetzte Event trägt user_id, jedes davor abgesetzte nicht. Die Formulierung in der Referenz — Parameter, die jedem nachfolgenden Event auf der Seite zugeordnet werden — begrenzt die Wirkung zeitlich nach vorn und auf das aktuelle Dokument. Eine klassische Multi-Page-Website setzt den Befehl deshalb bei jedem Seitenaufruf erneut ab, eine Single-Page-Application einmal für die Lebensdauer des Dokuments.
Auf der Verarbeitungsseite gehen die früheren Events nicht verloren. Analytics ordnet Events, die vor dem Setzen der User ID ausgelöst wurden, dieser User ID zu. Das dokumentierte Beispiel führt durch eine Sitzung, die abgemeldet beginnt: Event 1 und Event 2 tragen keine Kennung, der Nutzer meldet sich an, Event 3 folgt — und anschließend sind Event 1, 2 und 3 sämtlich der ID dieses Nutzers zugeordnet. Zwei Grenzen gelten. Die Zuordnung wird innerhalb einer Sitzung beschrieben, und sie reicht nicht in Daten zurück, die vor dem Bestehen der Implementierung erhoben wurden; solche Daten werden nicht erneut verarbeitet. Ob sie frühere, bereits abgeschlossene Sitzungen auf demselben Gerät umfasst, geht aus den Primärquellen nicht hervor.
Die Abmeldung ist das Spiegelbild. Der Wert wird auf null gesetzt — nicht auf einen leeren String, nicht auf ein Leerzeichen, nicht auf die Zeichenkette "null".
gtag('set', { 'user_id': null });
Analytics ordnet nachfolgende Events dieser User ID daraufhin nicht mehr zu: Im dokumentierten Beispiel bleiben die Events 1 bis 3 zugeordnet, Event 4 nicht. Eine erneute Anmeldung mit derselben Kennung innerhalb derselben Sitzung nimmt die Zuordnung wieder auf.
Der update-Parameter: zusammenführen statt neu initialisieren
Der set-Befehl beantwortet eine Frage: welcher Wert soll ab
jetzt mit allem mitreisen, was die Seite sendet. Ein zweites, enger gefasstes
Mittel beantwortet eine andere: wie sich eine bestehende Konfiguration ändern
lässt, ohne die Nebenwirkungen eines frischen config-Aufrufs. Dieses
Mittel ist der update-Parameter, übergeben innerhalb von
config selbst.
Auf
truegesetzt, führt derupdate-Parameter neue oder geänderte Parameter in die bestehende Google-Tag-Konfiguration zusammen, sendet für diese Aktualisierung aber keinpage_view-Ereignis. Üblich ist das in Single-Page-Anwendungen, um Parameter zu aktualisieren, ohne den Tag neu zu initialisieren.
Das Feld ist ein Wahrheitswert und steht standardmäßig auf
false. Genau diese Vorbelegung erklärt den doppelten Treffer aus
dem vorigen Abschnitt: ohne update gilt der Aufruf als frische
Konfiguration, und eine frische Konfiguration sendet einen
page_view.
gtag('config', 'G-XXXXXXXXXX', {
'update': true,
'page_location': 'https://example.com/new-page'
});
Zwei Unterschiede trennen das von set. Der erste ist die
Reichweite: update führt in die Konfiguration des einen genannten
Ziels zusammen, während set global für jedes folgende Ereignis und
jedes Ziel zuweist. Der zweite ist die Absicht: update überarbeitet,
was der Tag bereits hält, während set einen Wert obendrauf legt,
ohne anzutasten, was config besetzt.
Damit ist die Wahl einigermaßen klar. Eine nach der Anmeldung eintreffende
User ID gehört in set — sie ist eine globale Eigenschaft von allem,
was folgt. Ein Seitenwechsel in einer Single-Page-Anwendung gehört in
config mit update auf true, denn
page_location und page_title sind Konfiguration dieses
einen Streams, und der zugehörige page_view wird besser bewusst
gesendet als beiläufig erzeugt.
Der Weg über den Google Tag Manager
Tag Manager und gtag.js teilen sich ein einziges globales window.dataLayer; pro Seite wird nur ein solches Objekt unterstützt, und gtag() ist ein Wrapper, der seine Argumente hineinschiebt. Ein über GTM ausgespieltes Google Tag verarbeitet zusätzlich zu den in der Oberfläche konfigurierten Einstellungen auch gtag()-Befehle auf der Seite. Für gemeinsamen Kontext über mehrere Google Tags hinweg nennt die GTM-Hilfeseite gtag.js auf der Website selbst — mit dem Hinweis, dass globale Parameter von allen Google Tags der Website gelesen werden und nur unkritische Daten enthalten sollten.
Was die GTM-Oberfläche nicht bietet, ist ein fertiger Tag-Typ für ein spätes set. Die Variable Konfigurationseinstellungen setzt Parameter, die beim Laden des Google Tags geladen werden — ein Mechanismus zur Ladezeit; die Variable Ereigniseinstellungen ergänzt Parameter pro Event. Keine der beiden aktualisiert ein bereits laufendes Google Tag. Das containerseitige Äquivalent liegt eine Ebene unter der Oberfläche, in der Custom-Templates-API: gtagSet(object) schiebt einen gtag-set-Befehl in den Data Layer, der verarbeitet wird, sobald das aktuelle Event und die davon ausgelösten Tags abgeschlossen sind, und die Referenz garantiert, dass diese Aktualisierung im Container vor allen bereits im Data Layer wartenden Einträgen behandelt wird. Der Weg ist damit dokumentiert; es fehlt lediglich ein vorkonfigurierter Tag-Typ dafür, sodass die Aktualisierung über ein eigenes Template läuft. Ein fertiges Tag mit diesem Verhalten wird in der hier gesichteten Dokumentation nicht beschrieben, was ein negativer Befund ist und kein ausdrücklicher Ausschluss durch Google.
Die Warteschlange trennt die beiden Wege. Tag Manager verarbeitet Nachrichten nach dem First-in-first-out-Prinzip, eine nach der anderen in der Reihenfolge des Eingangs. Ein gtag()– oder dataLayer.push()-Aufruf aus dem Seitencode oder aus einem Custom-HTML-Tag reiht sich hinter allen ausstehenden Nachrichten ein, und die aktualisierten Werte stehen für das nächste Event nicht garantiert zur Verfügung; dasselbe gilt für einen generischen Data-Layer-Push aus Template-Code. Die beiden dedizierten Template-APIs sind die dokumentierte Ausnahme: gtagSet und das verwandte updateConsentState werden garantiert im Container vor allem verarbeitet, was in der Data-Layer-Warteschlange wartet. Die Einschränkung liegt also nicht am Container als solchem, sondern am darin gewählten Weg — ein roher Push gibt keine Reihenfolgegarantie, die Template-API schon.
Das Google Tag erneut auszulösen, um die Kennung einzuschleusen, ist aus einem zweiten Grund der falsche Hebel. Der config-Befehl stößt in manchen Produkten ein Pageview-Event an, in Google Analytics sendet er beim Laden des Tags page_view, und dasselbe Google Tag zweimal auf einer Seite zu konfigurieren, kann doppelte Daten oder vermischte Einstellungen verursachen. Dass ein zweites Auslösen des GTM-Google-Tags einen zweiten page_view erzeugt, ist eine naheliegende Schlussfolgerung aus diesen Bausteinen und keine Aussage, die Google für diesen Tag-Typ trifft. Eine Unterdrückung ist mit send_page_view: false möglich — im Snippet, global über set oder in der Variablen Konfigurationseinstellungen —, diese Einstellung trägt jedoch nicht über Seiten hinweg.
Eine Ankündigung vom 20. Mai 2026 gehört ins Bild: Neue Bereitstellungs-Snippets werden einheitlich sein und den gtag-config-Befehl entfallen lassen, wobei die Initialisierung über einen gtm init-Trigger konfiguriert wird, der auch auf den config-Befehl warten kann, um ein bestehendes Altsetup zu erhalten. Automatisch ändert sich nichts, das Verhalten auf der Seite wird als unverändert beschrieben, und das Installationsbeispiel in der Entwicklerdokumentation zeigt weiterhin gtag('config', 'TAG_ID');.
Der verwandte Fall: Consent Mode
Consent Mode folgt derselben Form — ein Wert, der beim Laden des Tags unbekannt ist und später ohne Neuladen übergeben wird — mit anderem Ziel und strengerer Reihenfolge. Standardmäßig sind keine Consent-Mode-Werte gesetzt. Der default-Befehl muss auf jeder Seite vor jedem Befehl laufen, der Messdaten sendet; in falscher Reihenfolge aufgerufen, wirken die Voreinstellungen nicht.
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'denied',
'wait_for_update': 500
});
Der Wert wait_for_update in Millisekunden steuert, wie lange das Tag wartet, bevor es Daten sendet, was für asynchron ladende Consent-Lösungen von Bedeutung ist; sind Netzwerkanfragen im Spiel, werden mindestens 500 Millisekunden nahegelegt. Voreinstellungen lassen sich nach Region gemäß ISO 3166-2 differenzieren, wobei die spezifischere Region den Vorrang hat.
Das Update geschieht auf der Seite, auf der die Entscheidung fällt, vor jedem Seitenwechsel, denn Consent Mode speichert die Auswahl nicht selbst.
gtag('consent', 'update', {
'ad_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted',
'analytics_storage': 'granted'
});
Ein Reload ist nicht erforderlich, und der Zustandswechsel erzeugt selbst ein Signal: Consent-State-Pings werden von jeder Seite gesendet, auf der Consent Mode aktiviert ist, und werden für einige Tags zusätzlich ausgelöst, wenn der Zustand von denied auf granted wechselt. In der erweiterten Implementierung laden die Tags sofort und senden, solange die Einwilligung verweigert ist, Messungen ohne Cookies. Innerhalb von Tag-Manager-Templates ist der gtag-consent-Befehl ausdrücklich nicht zu verwenden — die API updateConsentState existiert, damit Consent-Updates vor wartenden Data-Layer-Einträgen verarbeitet werden, dieselbe Reihenfolgegarantie, die gtagSet für Parameter mitbringt.
Fallstricke und Prüfungen
- Geltungsbereich, kein Überschreiben. Ein spätes
setschreibt nicht um, wasconfigoder ein Parameter auf Event-Ebene bereits hält. Wo ein Wert sich durchsetzen muss, gehört er in den höherrangigen Geltungsbereich. - Seitengrenzen und Reihenfolge.
setreicht nur nach vorn und nur innerhalb des aktuellen Dokuments; serverseitig gerenderte Navigationen brauchen den Befehl erneut. Das Snippet muss oberhalb der Event-Befehle stehen, undsetgehört überconfig, wenn mehrere Tag-IDs die Werte erben sollen. - Weg durch den Container. Innerhalb von GTM liegt die Reihenfolgegarantie bei den Template-APIs. Ein später Wert, der aus einem Custom-HTML-Tag gepusht wird, konkurriert mit der Warteschlange; derselbe Wert, über
gtagSetin einem eigenen Template übergeben, nicht. - Hygiene der Kennung. Ein User-ID-Wert ist auf 256 Zeichen begrenzt, laut Measurement-Protocol-Referenz ausschließlich UTF-8, und darf keine Informationen enthalten, mit denen ein Dritter die Identität eines Nutzers bestimmen könnte; E-Mail-Adressen und private Mobilfunknummern werden als unzulässig genannt. Ob eine gehashte Ableitung zulässig ist, lässt sich aus den Primärquellen nicht klären.
- Keine benutzerdefinierte Dimension auf der ID. Von der Registrierung von
user_idals benutzerdefinierte Dimension wird wegen der sehr hohen Zahl unterschiedlicher Werte abgeraten. - Berichtsidentität. Die gerätebasierte Berichterstattung zeigt keine User-ID-Analyse; erforderlich ist Blended oder Observed. Die Wahl beeinflusst weder Erhebung noch Verarbeitung.
- Verifikation.
gtag('get', …)liestclient_id,session_id,session_numberundgclidzurück, und ein perseteinem dieser Felder zugewiesener Wert hat Vorrang vor dem intern abgeleiteten. Tag Assistant weist Consent in den getrennten Spalten On-page Default und On-page Update aus.
Fazit
Die Abwägung ist einseitig. Ein geladenes Google Tag neu zu konfigurieren, um einen Wert anzuhängen, kostet eine doppelte Initialisierung, riskiert vermischte Einstellungen und einen zweiten page_view und bringt nichts ein, was ein einzelner set-Befehl nicht liefert. Für die User ID fällt die Rechnung noch klarer aus, weil die Verarbeitungsseite die Lücke schließt, die der Browser offen lässt: Bereits innerhalb der Sitzung gesendete Events werden der Kennung nachträglich zugeordnet, die Hits vor dem Login sind also nicht verloren.
Was der Ansatz nicht leistet, ist das Überschreiten von Grenzen, die ihm nie gegeben wurden. Er überdauert keinen Seitenwechsel, er sticht keinen Wert aus, den ein höherer Geltungsbereich bereits hält, und er reicht nicht in Daten zurück, die vor dem Bestehen der Implementierung erhoben wurden. Consent Mode zeigt dasselbe Muster aus anderem Blickwinkel: eine dokumentierte Voreinstellung, ein späteres Update auf derselben Seite, ein Zustandswechsel, der die Tags ohne Reload erreicht. Wo ein Container das Tag verwaltet, ist die Warteschlange die Randbedingung, um die herum zu entwerfen ist, und gtagSet zusammen mit updateConsentState ist die dokumentierte Ausnahme davon — zum Preis eines eigenen Templates. Die angekündigte Vereinheitlichung von Google Tag und Tag Manager, im August 2026 noch im Futur, ist eher zu beobachten als vorwegzunehmen.