Kurz vorab: Sie richten Conversion Tracking in Shopware 6 ein, indem Sie den Google Tag Manager über das BuI-Hinsche-Plugin laden, pro Seitentyp einen E-Commerce-DataLayer in Twig pflegen, das Purchase-Event auf der Order-finish-Page mit Bestellnummer, Netto-Wert und Währung feuern und den GTM-Load sauber an die Einwilligung (CCM19 / Consent Mode v2) koppeln. Diese Anleitung führt Sie Schritt für Schritt durch genau diese Kette – inklusive der Code-Beispiele und der Fehlerbilder, die in der Praxis am häufigsten auftauchen.
Wir betreuen diesen Stack auf Produktionsshops. Die Felddetails in diesem Beitrag stehen so in keiner Plugin-Doku – wir haben sie live gegen einen laufenden Shopware-6-Shop verifiziert. Wenn Sie das Setup lieber abgeben möchten, lesen Sie hier, wie Sie Conversion Tracking für Shopware einrichten lassen.
Die drei Bruchstellen, an denen Shopware-Tracking fast immer scheitert
Bevor wir bauen, lohnt der Blick auf die drei Stellen, an denen in der Praxis fast jedes Setup kippt. Wer sie kennt, spart sich die meiste Debug-Zeit.
- Container-ID fehlt. Im verbreiteten BuI-Hinsche-Plugin („Google Tag Manager / GA4“) ist die GTM Container ID ein Pflichtfeld. Ist es leer, lädt gar nichts – und jede weitere Einstellung läuft ins Leere. Das ist die häufigste Ursache für „es trackt nichts“.
- Das Consent-Gate blockt still. Die Option „Shopware Cookie Unterstützung“ koppelt den GTM-Load an das Cookie
wbm-tagmanager-enabled=1. Ohne Einwilligung wird dieses Cookie nie gesetzt, GTM lädt nie – obwohl die Konfiguration auf den ersten Blick korrekt aussieht. - Doppelte Tags zählen doppelt. Läuft parallel ein zweites GA4-/GTM-Plugin oder ist der Analytics-Tab im Sales-Channel befüllt, feuern Conversions doppelt. Ihre Zahlen sind dann zu hoch, der ROAS verzerrt. Vor jedem Setup gehören andere GA4-/GTM-Plugins deaktiviert und der Analytics-Tab geleert.
Merken Sie sich diese drei Verdächtigen. Wenn am Ende trotz sauberer Konfiguration nichts feuert, liegt es fast immer an einem davon – plus dem Cache, dazu unten mehr.
Google Tag Manager in Shopware 6 einbinden: 3 Wege im Vergleich
Für den Google Tag Manager in Shopware 6 gibt es drei Wege. Sie unterscheiden sich nicht im Installationsaufwand, sondern darin, ob am Ende ein sauberer E-Commerce-DataLayer und ein korrektes Consent-Mapping herauskommen.
Weg A – manuell ins Theme
Sie kopieren das GTM-Snippet selbst in Ihr Theme. Technisch möglich, in der Praxis fehleranfällig: keine Anbindung an die Shopware-Consent-Logik, kein automatischer E-Commerce-DataLayer, und ein Tippfehler im Inline-Script legt schnell das gesamte Tracking lahm. Für einen produktiven Shop ist das der riskanteste Weg.
Weg B – BuI-Hinsche-Plugin (für die meisten Shops die richtige Wahl)
Das Plugin platziert GTM und baut den E-Commerce-DataLayer gleich mit. Dafür injiziert es drei Inline-Scripts: #wbmTagMangerDefine setzt die gtmContainerId, meldet die Consent-Unterstützung und pusht ein erstes User-Event; #wbmTagMangerDataLayer schreibt pro Seite ecommerce, user und das passende Event in Twig; #wbmTagManger ist der Loader samt Consent-Logik. Praktisch: Über „Deaktiviere GTM Container“ schalten Sie das Tracking vorübergehend ab, ohne die ID zu verlieren, und Optionen wie „Produkt-Klicks in Listings“ (select_item) oder „Klicks auf Zur-Wunschliste“ (add_to_wishlist) liefern zusätzliche Signale, die oft vergessen werden.
Weg C – Plugin plus Stape Server-Side
Aufbau wie Weg B, ergänzt um einen Custom-Loader auf einer eigenen First-Party-Subdomain (d.ihre-domain.de). Das umgeht Adblocker und macht das Tracking gegen Browser-Restriktionen widerstandsfähiger. Die Server-Side-Mechanik beschreiben wir weiter unten im Detail.
Ein häufiger Einwand: „Ab Shopware 6.7 geht GTM doch auch ohne Plugin.“ Stimmt – einbinden lässt sich der Container grundsätzlich auch nativ. Aber der saubere E-Commerce-DataLayer und das korrekte Consent-Mapping kommen aus dem Plugin. Für ein Setup, dem Sie Ihre Budgetentscheidungen anvertrauen, bleibt das Plugin der praktische Weg.
GTM-Container-ID in Shopware eintragen (Schritt für Schritt)
Die GTM-Container-ID tragen Sie im Plugin unter Konfigurieren → Feld „GTM Container ID“ ein, im Format GTM-XXXXXXX. Das Feld ist Pflicht: Bleibt es leer, lädt nichts – egal, was sonst eingestellt ist.
So gehen Sie vor:
- Container-ID eintragen. Plugin öffnen,
GTM-XXXXXXXins Pflichtfeld setzen. Auch wenn Sie später Stape Server-Side mit eigener Loader-URL nutzen: Die echteGTM-XXXXXXXbleibt hier stehen – sie speist die<noscript>-Iframe und wird intern als Argument durchgereicht. - Consent-Anbindung aktivieren. „Shopware Cookie Unterstützung“ auf EIN. Damit erscheint bei CCM19 bzw. dem Shopware-Consent der Eintrag „Google Tagmanager“, und der Load wird sauber auf das Cookie
wbm-tagmanager-enabled=1gegated. - DataLayer pro Seite pflegen. Unter Marketing → Google Tag Manager legen Sie je Seitentyp den DataLayer an (Modul = Symfony-Route, Eigenschaften = Keys und Twig-Werte). Diese Konfiguration übertragen Sie per JSON-Export/Import sauber von Test nach Produktion.
- Caches leeren – sonst sehen Sie Ihre Änderung nicht. Das ist der Grund Nummer eins für „bei mir wirkt nichts“. Nach jeder Config- oder Theme-Änderung im Shopware-Admin „Caches leeren“, zusätzlich
bin/console cache:clear, dann Varnish bzw. Reverse-Proxy und CDN/Cloudflare purgen. Prüfen Sie anschließend im ausgelieferten HTML, ob die Änderung wirklich angekommen ist – nicht nur im Backend.
Der Cache-Schritt klingt banal, ist aber die mit Abstand häufigste Ursache für „ich habe alles richtig eingestellt und trotzdem ändert sich nichts“. Leeren Sie ihn auf allen Ebenen:
# Shopware-Cache auf der Konsole leeren bin/console cache:clear # danach: Varnish / Reverse-Proxy purgen und CDN/Cloudflare-Cache leeren, # dann das ausgelieferte HTML pruefen (View Source), nicht nur das Backend.
Google Ads Conversion Tracking in Shopware: Käufe, Wert & Enhanced Conversions
Das Google Ads Conversion Tracking in Shopware feuert das Purchase-Event auf der Order-finish-Page – also nach abgeschlossener Bestellung, nicht auf der Bestätigungsseite davor. Der entscheidende Vorteil: Es nutzt die Order-Daten ({{ page.order.* }}) und funktioniert dadurch zuverlässig auch für Gäste, die nicht eingeloggt sind. Kein Login, trotzdem ein vollständiges Conversion-Signal.
Drei Felder sind dabei Pflicht – und jedes hat eine konkrete Aufgabe:
transaction_id(={{ page.order.orderNumber }}) verhindert, dass derselbe Kauf doppelt gezählt wird, etwa beim Neuladen der Danke-Seite.valueträgt den Bestellwert – entscheidend ist hier: netto, nicht brutto, sonst blähen Sie Ihren ROAS in Google Ads auf.{{ page.order.price.netPrice }}liefert den Netto-Bestellwert und ist die saubere Baseline. Wer als Conversion-Wert ausschließlich den reinen Warenwert ohne Versandkosten zählen will, berechnet ihn zusätzlich per Twig-Loop überlineItems(abzüglichcalculatedTaxes).currency(={{ context.currency.isoCode }}) liefert die Währung, damit Google den Wert korrekt verrechnet.
So sieht der DataLayer-Push für ein Purchase-Event aus:
{
"event": "purchase",
"ecommerce": {
"transaction_id": "{{ page.order.orderNumber }}",
"value": "{{ page.order.price.netPrice }}",
"currency": "{{ context.currency.isoCode }}"
}
}
Den entscheidenden Schritt darüber hinaus liefern Enhanced Conversions. Dabei geben Sie gehashte Kundendaten – etwa die E-Mail-Adresse – verschlüsselt an Google mit. In Geschäftsnutzen übersetzt: Damit sehen Sie auch die Käufe, bei denen der Kunde dem Cookie-Banner nicht zugestimmt hat. Zusammen mit der Modellierung aus Consent Mode v2 schließt das einen großen Teil der Messlücke, die durch Cookie-Ablehnungen entsteht. Smart Bidding bekommt vollständigere Signale – und bietet auf echte Verkäufe statt auf das, was zufällig durchs Banner gekommen ist.
SEA-Experte: Bernhard Prange
Google Ads Freelancer & Tracking-Spezialist – seit über 10 Jahren im Performance-Marketing. Sie sprechen direkt mit Bernhard: kein Junior, keine Zwischeninstanz.
Consent Mode v2 & CCM19 in Shopware: DSGVO-konform tracken
Sie tracken DSGVO-konform, indem Sie sich für genau einen Weg entscheiden: GTM erst nach Einwilligung laden (Methode A) oder GTM immer laden, aber bis zur Einwilligung blockierte Signale senden (Methode B per Consent Mode v2). Beide Wege funktionieren rechtssicher. Was zu Abmahnrisiko und kaputten Daten führt, ist das Vermischen.
CCM19 ist als Shopware-Plugin (papoo-ccm19-integration6) der praktische Consent-Manager dafür. Es lädt vor dem Tag-Manager und meldet die Einwilligung über CCM19.embeddingAccepted und CCM19.consentStateChanged in den dataLayer. Cookiebot lässt sich alternativ einsetzen, das Prinzip bleibt dasselbe. Wichtig: CCM19 mappt die erteilte Einwilligung auf die Shopware-Cookies google-analytics-enabled=1, google-ads-enabled=1 und wbm-tagmanager-enabled=1.
Methode A – GTM bis zur Einwilligung blocken
Sie tragen den „Google Tag Manager“ als geblocktes Embedding in CCM19 ein. CCM19 lädt zuerst, GTM erst nach dem Klick auf „Akzeptieren“, weil dann wbm-tagmanager-enabled=1 gesetzt wird. Im Container konsumieren Sie die Einwilligung über einen Custom-Event-Trigger auf CCM19.embeddingAccepted und eine dataLayer-Variable mit dem Embedding-Namen. Dieser Weg passt direkt zum Cookie-Gate des Plugins und zur Option „Shopware Cookie Unterstützung“.
Methode B – Consent Mode v2
Hier markieren Sie das GTM-Embedding als „technisch notwendig“. GTM lädt damit immer und sendet vor der Einwilligung den Consent-Status default = denied. Sie blocken den Tag-Manager nicht und aktivieren am GTM-Embedding selbst keine Consent-Typen – die CCM19-Doku warnt ausdrücklich davor, weil das sonst alle Typen auf granted zwingt. Die beiden v2-Neuerungen ad_user_data und ad_personalization müssen neben ad_storage und analytics_storage vorhanden sein.
Nicht mischbar. Methode A und B schließen sich aus. Bei Methode B kollidiert das wbm-tagmanager-enabled-Gate mit dem Prinzip „GTM lädt immer“ – das Gate muss also effektiv offen stehen, und consent default wie consent update dürfen nur von einem Owner kommen: entweder vom Consent-Mode-Tag im Container oder vom plugin-eigenen gtag('consent','update', …). CCM19 setzt in diesem Fall nur die Cookies. Eine Genauigkeit, die viele Anleitungen falsch darstellen: Das gtag('consent','default', {…wait_for_update:1000}) und das spätere …'update'…granted stammen vom Consent-Mode-Tag bzw. vom Plugin, nicht von CCM19 – CCM19 emittiert kein consent default/update.
Unabhängig vom Weg gilt: andere GA4-/GTM-Plugins deaktivieren und den Analytics-Tab im Sales-Channel leeren, sonst entstehen doppelte Tags.
Häufige Fehler: googleTag is not a function & Unexpected token if
googleTag is not a function und Unexpected token 'if' haben fast immer dieselbe Ursache: ein falsch eingefügter Override im Feld „GTM Funktion überschreiben“. Das Plugin wrappt dieses Feld wörtlich als let googleTag = «Ihr Feldinhalt»; und ruft anschließend googleTag(window, document, 'script', 'dataLayer', gtmContainerId) auf. Das Feld muss deshalb ein Funktionsausdruck sein – kein selbstaufrufendes IIFE.
googleTag is not a function. Sie haben das komplette Stape-IIFE(function(w,d,s,l,i){…})(window,…)ins Feld kopiert. Daraus wirdlet googleTag = (function(){…})(…);– der Ausdruck ruft sich selbst auf und liefertundefinedzurück. Der spätere AufrufgoogleTag(...)läuft dann gegenundefined. Fix: nur die Funktion ohne äußere Klammern und ohne Sofortaufruf einfügen, beginnend mitfunction(w,d,s,l,i){.Unexpected token 'if'. Hier fehlt das Semikolon nach der Override-Funktion. Ohne;stehtlet googleTag = function(){…} if(…)in einer Zeile, die automatische Semikolon-Ergänzung greift nicht, und der gesamte Inline-Block stirbt. Fix: das Feld mit};abschließen – genau eine schließende Klammer plus Semikolon.undefined is not a function(cloud.ccm19.de / wbm-tag-manager-analytics). Das ist ein Folgefehler, kein eigener Bug. Stirbt der Inline-Block am SyntaxError oben, kaskadiert der Ausfall überpapoo-ccm19-integration6.js→wbm-tag-manager-analytics.js→cloud.ccm19.de/app.js(insertBefore). Debuggen Sie nicht diese Folgemeldung – beheben Sie den ursprünglichen SyntaxError, dann verschwindet sie mit.- Stape-URL-Falle. Lassen Sie im Snippet das
…?"+istehen, übergibt das Plugini= Ihre GTM Container ID und baut daraus…/loader.js?GTM-XXXX. Das ist die falsche URL, der Loader lädt kaputt oder gar nicht. Stape braucht seine eigene?3qde=-Query – die URL also hardcoden, kein+i. - Doppel-Loader. Sind „GTM Funktion überschreiben“ und „Eigene Tagmanager URL“ gleichzeitig aktiv, wird derselbe Tag zweimal geladen. Verwenden Sie nur einen Loader.
- „GTM lädt nie“. Zwei Klassiker: Die Container ID ist leer (Pflichtfeld), oder
wbm-tagmanager-enabledwird nie gesetzt, weil bei Methode A keine Einwilligung erteilt wurde.
Ein korrekt befülltes Override-Feld startet mit function(w,d,s,l,i){ (keine führende Klammer), hat die URL hardcodiert (kein +i) und endet mit }; (genau ein } plus Semikolon, keine überzählige )):
// Feld "GTM Funktion ueberschreiben" - Funktionsausdruck fuer Stape (KEIN IIFE)
function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],j=d.createElement(s);
j.async=true;
j.src="https://d.ihr-shop.de/abc.js?3qde=IHRE_STAPE_QUERY"; // hardcodiert, kein +i
f.parentNode.insertBefore(j,f);
};
DataLayer & Server-Side Tracking in Shopware 6
Den DataLayer pflegen Sie in Shopware 6 pro Route und Seitentyp in Twig – unter „Marketing → Google Tag Manager“ bzw. „Einstellungen → Google Tag Manager → Routen & DataLayer“. Dort hinterlegen Sie Events wie AddToCart, RemoveFromCart, Login, Confirm, Listing, ProductDetail und Purchase, jeweils mit den passenden Kontextvariablen.
Verfügbar sind unter anderem {{ context.customer.email }} / {{ context.customer.id }}, {{ context.customer.customerNumber }}, {{ context.currentCustomerGroup.name }}, der Warenkorb-Token {{ context.token }} und {{ context.currency.isoCode }}. Auf der Order-finish-Page kommen Order-Daten hinzu: {{ page.order.orderNumber }}, {{ page.order.price.netPrice }}, {{ page.order.lineItems }} und {{ page.order.orderCustomer.email }}.
Der Knackpunkt bei der Datenqualität: Login- und Account-Variablen liefern nur für eingeloggte Kunden Werte. Eine sessionweite Identität auch für anonyme Nutzer stellen Sie über den Warenkorb-Token {{ context.token }} her – das verbessert die Identitätsfeststellung für serverseitiges Tracking spürbar. Das Purchase-Event auf der Order-finish-Page nutzt dagegen {{ page.order.* }} und greift dadurch zuverlässig auch für Gäste; als Conversion-Wert dient der Netto-Bestellwert {{ page.order.price.netPrice }}, bei Bedarf verfeinert um den reinen Warenwert ohne Versand per Twig-Loop über lineItems (abzüglich calculatedTaxes).
Mit user_data im selben Push reichern Sie das Purchase-Event für Enhanced Conversions und Server-Side an:
{
"event": "purchase",
"ecommerce": {
"transaction_id": "{{ page.order.orderNumber }}",
"value": "{{ page.order.price.netPrice }}",
"currency": "{{ context.currency.isoCode }}"
},
"user_data": {
"email_sha256": "{{ page.order.orderCustomer.email }}"
}
}
Server-Side Tracking mit Stape
Beim serverseitigen Setup läuft der Custom Loader First-Party über eine eigene Subdomain d.ihr-shop.de. Die Requests gehen also über Ihre eigene Domain und verschlüsselt – Adblocker und ITP greifen seltener, und Sie erfassen Käufe, die ein rein clientseitiges Tag verliert. Smart Bidding bietet damit auf vollständigere Daten statt auf eine löchrige Stichprobe. Wichtig: nur ein Loader gleichzeitig – „GTM Funktion überschreiben“ XOR „Eigene Tagmanager URL“.
Vorsicht beim Cookie Keeper. Stapes Cookie Keeper persistiert einen Master-Identifier (Cookie, Local Storage, DOM, JS-Variable oder Stape User ID). Bei manchen Identifier-Typen injiziert er ein cross-origin-iframe auf d.ihr-shop.de. Microsoft Claritys Session-Recorder läuft jedes iframe ab, trifft dieses Frame und wirft einen unbehandelten SecurityError – am härtesten auf Safari/WebKit mit ITP. Das spammt nicht nur die Konsole, es bricht Claritys Init ab, sodass window.clarity undefiniert bleibt. Lösung: Cookie Keeper deaktivieren oder das Tagging same-origin ausliefern und das Clarity-Beacon über den First-Party-sGTM-Endpoint routen. Ein Detail für die Verifikation: Stape proxyt mehrere Tags über einen konstanten Pfad (…/<loader>/r?<base64>), nur die Base64-Query unterscheidet sie – Duplicate-Script-Prüfer melden GA4 und Ads sonst fälschlich als „dasselbe Script zweimal“. Erst die Query dekodieren.
Derselbe DataLayer trägt später auch weitere Werbekanäle, ohne dass Sie das Tracking neu aufbauen müssen.
Praxisbeispiel: Login-Event im DataLayer für bessere Identitätsfeststellung
Wie sich die Identitätsfeststellung in einem echten Shopware-6-Shop verbessern lässt, haben wir in einem eigenen Beitrag dokumentiert – mit demselben Plugin-Stack (BuI-Hinsche-Extension „Google Tag Manager / GA4 / Server-Side Tracking“), den auch diese Anleitung behandelt.
Vorher. Das Standard-Setup liefert Kundendaten nur für eingeloggte Nutzer. Anonyme Sessions bleiben ohne stabile Identität – die Zuordnung von Klick zu Conversion ist lückenhaft, die Audience-Qualität in Google Ads leidet.
Nachher. Beim erfolgreichen Login schreiben wir über die Twig-Route frontend.account.home.page ein login-Event mit Kundendaten in den DataLayer: user_data.email sowie user.id, user.number und user.group. Die sessionweite Identität für anonyme Nutzer stellen wir zusätzlich über den Warenkorb-Token {{ context.token }} her. Das Purchase-Event auf der Order-finish-Page nutzt unabhängig davon {{ page.order.* }} und greift damit zuverlässig auch für Gäste – inklusive transaction_id, Wert und Währung.
{
"event": "login",
"user_data": { "email": "{{ context.customer.email }}" },
"user": {
"id": "{{ context.customer.id }}",
"group": "{{ context.currentCustomerGroup.name }}",
"token": "{{ context.token }}"
}
}
So lässt sich die Identitätsfeststellung von Nutzern im Onlineshop wesentlich verbessern – die Grundlage für bessere Conversion-Zuordnung und sauberere Audiences im serverseitigen Tracking. Den vollständigen Weg inklusive Twig-Konfiguration lesen Sie hier: so haben wir das Login-Event im DataLayer umgesetzt.
Was ist mit Shopware 5?
Das Prinzip bleibt gleich – GTM-Container, DataLayer und Consent-Gate funktionieren konzeptionell identisch. Die konkreten Twig-Routen und Plugin-Felder unterscheiden sich aber zwischen Shopware 5 und Shopware 6 (und bis 6.7). Wenn Sie auf Shopware 5 sitzen, übertragen Sie die Logik dieser Anleitung sinngemäß: Container-ID als Pflicht, DataLayer pro Seitentyp, ein Consent-Gate, ein Loader. Die Feldnamen heißen anders, die drei Bruchstellen bleiben dieselben.
Häufige Fragen
Brauche ich ab Shopware 6.7 noch ein Plugin für GTM?
Theoretisch nein – GTM lässt sich ohne Plugin einbinden. In der Praxis liefert aber erst das Plugin den sauberen E-Commerce-DataLayer und das Consent-Mapping. Wer das von Hand baut, riskiert genau die Fehlerbilder aus diesem Artikel.
Funktioniert das Conversion Tracking auch für Gäste ohne Login?
Ja. Das Purchase-Event feuert auf der Order-finish-Page und nutzt die Order-Daten ({{ page.order.* }}), nicht den Login-Status. Damit werden Käufe auch ohne Kundenkonto erfasst – inklusive transaction_id, Bestellwert und Währung.
Warum stimmen meine Google-Ads-Conversions nicht mit den Shopware-Bestellungen überein?
Meist liegt es an einer von drei Ursachen: doppelte Tags durch parallele Plugins (Überzählung), ein durch fehlende Einwilligung blockiertes Tag (Unterzählung) oder ein falscher Wert (Brutto statt Netto). Enhanced Conversions und Consent-Mode-Modellierung schließen zusätzlich die Lücke aus Cookie-Ablehnungen.
Brauche ich Server-Side Tracking, oder reicht clientseitiges GTM?
Clientseitiges GTM reicht für den Start. Server-Side über Stape lohnt sich, sobald Adblocker und ITP messbar Conversions kosten – dann läuft das Tagging First-Party über d.ihr-shop.de und erfasst mehr Käufe.
Ist das Setup rechtssicher und DSGVO-konform?
Ja, wenn Sie sich konsequent für Methode A oder Methode B entscheiden und die Consent-Signale von genau einem Owner kommen lassen. CCM19 (oder Cookiebot) steuert die Einwilligung, GTM lädt oder feuert erst entsprechend. Das Vermischen beider Methoden ist die häufigste Ursache für lückenhafte oder unsaubere Erhebung.
Tracking-Setup-Checkliste als PDF
Holen Sie sich die kompakte Checkliste für ein sauberes Shopware-Conversion-Tracking-Setup direkt ins Postfach – die Verdächtigen aus diesem Artikel auf einen Blick.
Lieber abgeben statt selbst bauen?
Diese Anleitung deckt den kompletten technischen Weg ab. Wenn Sie das Setup nicht selbst aufbauen, sondern sauber und verifiziert übergeben möchten, übernehmen wir das aus einer Hand – inklusive Tracking-Check Ihres bestehenden Setups. Mehr dazu, wie Sie Conversion Tracking für Shopware einrichten lassen.


