14.10.2024
Zuverlässiges Tracking von iFrames (ohne Consent-Konflikte)
Wenn es um Tracking-Setups geht, waren iFrames schon immer eine besondere Herausforderung. Für einen Inhalt in einem iFrame als Teil einer beinhaltenden Seite ein sinnvolles Tracking aufzusetzen, das in den Kontext der restlichen Domain passt, verursacht oft eine Menge Arbeit. Kommen die Inhalte für den iFrame auch noch von einer anderen Domain, fängt der Spaß so richtig an: Cross-Domain-Tracking, getrennte Persistenz in Form von Cookies und Browser-Speicher, wackelige Kommunikation zwischen den beteiligten Domains über Parameter, Hürden durch moderne Browser-Tracking-Protection-Maßnahmen an allen Fronten. Dazu gesellt sich die “Same Origin” Policy als Blockade für alle Versuche, aus der Hauptseite “in” den iFrame zu schauen (oder gar umgekehrt). Und dann ist da auch noch das Thema Zustimmung. Wer fragt wann wonach, bevor Daten gesendet werden können? Das alles ist ein ziemlicher Wust aus potenziellen Problemen. Zum Glück gibt es aber eine ganz einfache Lösung: Das Tracking bleibt auf der beinhaltenden Seite und alles, was im iFrame passiert, wird über Messages kommuniziert.
Messages statt Tracking
"Gähn" mag der eine oder andere jetzt denken. Nicht zu unrecht, denn das ist weder eine neue Technik, noch ein besonderer Geheimtipp. Trotzdem scheint ein Löwenanteil von auf Websites verbauten iFrames nicht auf dieses Mittel zu setzen - mit oft enormen Problemen für Datenschutz, Datenqualität, Stabilität und Wartungsaufwand. Dieser Blogpost zeigt auf, warum diese Variante i. d. R. allen anderen Optionen vorzuziehen (und wie einfach sie zu nutzen) ist.
Hinweis: Dieser Beitrag basiert auf meinem im Mai 2023 in Ausgabe 1 des Analytics Pioneers Magazins erschienen Beitrag "Keine Angst vor iFrames!". Da es aber ein Dauerthema ist, wollte ich ihn hier nun auch in digitaler Form anbieten. Das Magazin bietet regelmäßig umfangreiche Beiträge zu Digital Analytics Themen und ich kann es nicht nur als Autor, sondern vor allem als Leser empfehlen!
iFrames sind stets ein Teil eines Ganzen
Wo immer ein iFrame eingesetzt wird, ist er nur sehr selten dafür verantwortlich, den gesamten Inhalt einer Seite zu bestimmen. Was im iFrame stattfindet, bildet deshalb üblicherweise nur einen Teil des Geschehens ab, welches evtl. vermessen werden soll. Meistens existiert eine mit nennenswerten eigenen Inhalten ausgestattete „Hauptseite“, in der der iFrame eingebunden ist. Dort befindet sich als Minimum die Navigation der Website, welche die iFrame Inhalte von der eigenen oder einer fremden Domain laden, aber im Kontext der eigenen Inhalte anbieten möchte. Das kann z. B. eine externe Anwendung sein, die einen Buchungsprozess aus mehreren Schritten (= auf mehreren URLs) abbildet, Informationen wie Termine o. Ä. einer externen Datenbank anzeigt oder andere dynamische Elemente bietet, die auf Hauptseite angezeigt werden sollen. Selbst iFrames, die den kompletten Inhalt bestimmen, sind üblicherweise aus einem guten Grund in einem iFrame auf einer anderen Seite unter einer anderen URL „eingefangen“ und dann eben Teil eines Verbundes von mehreren Inhalten: Der Website selbst. Aus Sicht des Trackings stecken die Hauptseite und deren Domain den Rahmen (oder besser: Kontext) für typische Tracking-Aufgaben ab.
Bei der Nutzung der iFrame-Inhalte entstehen Events. So ändern sich ggf. URLs der dargestellten Inhalte, wenn eine Formularstrecke ausgefüllt wird. Oder es entstehen andere Ereignisse (selbst E-Commerce ist hier ggf. ein Thema), wenn NutzerInnen mit den Inhalten interagieren. Sind diese Aufrufe oder sonstigen Ereignisse „trackingwürdig“, muss die Vermessung irgendwie implementiert werden.
Klassischer Ansatz: Tracking aus dem iFrame
Der typische, jedoch nie optimale Weg ist der Einbau von Trackingcodes direkt in den iFrame-Inhalten. Im „Bestfall“ ist dort ein Tag Manager verbaut, der entweder das gleiche Tracking enthält, das auf dem Rest der Website im Einsatz ist… oder es ist ein separater Container, der wiederum dennoch ein mehr oder weniger vollständiges Tracking enthält.
Spaßkiller „Consent“
Sieht man von allen Herausforderungen ab, die bei einem Betrieb auf unterschiedlichen Domains noch hinzufügt und konzentriert sich „nur“ auf das Thema Consent, ist ein solches Setup spätestens seit 2018 mit einem großen Problem konfrontiert: Alle Erstbesuche werden sowohl in der Hauptseite einen Consent-Dialog auslösen, als auch im iFrame selbst, so dass dieser zweifach „weggeklickt“ werden muss, um endlich an die Inhalte zu gelangen. Wer macht das schon?
Jedenfalls dann, wenn man sich beim Tracking im iFrame überhaupt die Mühe gemacht hat, an die Consent Implementierung zu denken. In der Praxis findet in einem iFrame hingegen oft eine ganze Menge an Tracking ungehindert statt, was man der Hauptseite Kraft Zustimmungs-Konfiguration eigentlich untersagt hat.
Hohe Komplexität, geringe Stabilität
Dazu gesellen sich weitere Stolpersteine, die je nach gewählter Lösung unterschiedlich groß ausfallen. Bei einem gemeinsamen Container für alle Inhalte besteht zum Beispiel die permanente Gefahr, dass eine Änderung, welche eigentlich nur für die Hauptwebsite „gedacht“ war, beim Ausführen im iFrame ungewollte Nebenwirkungen hat. Oder dort gar nicht funktioniert, obschon es so gedacht war.
Auch wird ein dataLayer bei beiden Teilen i. d. R. anders aussehen, weil die Daten normalerweise aus unterschiedlichen Quellen stammen. Was also bei einem Event auf der Hauptwebsite zur Verfügung steht, fehlt ggf. im iFrame und sorgt für Lücken bei Ereignisparametern.
Wechselt man das Consent Tool, erfordert dies oft eine Menge zusätzlicher Arbeit, wenn die Consent-Lage „irgendwie“ an den iFrame übergeben wird (statt dort das Tool nochmals zu laden); bei Verwendung getrennter Container kommen Synchronisierungsherausforderungen dazu. Und bei Tests wird der Part, welcher „nur“ im iFrame stattfindet, stets zu kurz kommen. Obschon gerade hier gern die wichtigsten Ereignisse stattfinden.
Besser: Tracking ausschließlich aus der Hauptseite
Bei all diesen Problemen ist es kein Wunder, dass man sich wünschen würde, alle Inhalte im iFrame wie echte Teile der Hauptseite zu behandeln. DOM Elemente im iFrame für Trigger nutzen, URL Änderungen mitbekommen, die dortigen dataLayer-Inhalte wie die “eigenen“ behandeln.
Ein Teil dessen ist in einigen Browsern sogar noch umsetzbar, solange nur eine Domain im Spiel ist. Das ist aber a) nur selten der Fall und b) zu unsicher in der Nutzbarkeit in der modernen Browserlandschaft, so dass man einen anderen Weg gehen muss: der iFrame meldet alles, was „trackingwürdig“ ist, an die Hauptseite. Diese entscheidet (in Form entsprechender Trigger im Tag Manager zum Beispiel) selbst, was davon relevant für das eigene Tracking-Setup ist und im Rahmen einer bestehenden Consent Entscheidung an einzelne oder alle potentiellen Empfänger weitergegeben werden darf.
Um also sämtliche Probleme mit einer Synchronisierung von IDs, Cookies etc. zwischen Haupt- und iFrame-Seite zu eliminieren, wird das Tracking komplett aus dem iFrame herausgehalten. Er wird wieder zur Black Box, sowohl für die Hauptseite (das war schon immer so), als auch für Trackingdienste wie Google Analytics (das ist neu).
Mittels Nachrichten lässt der iFrame ersatzweise die Hauptseite wissen, was gerade im iFrame passiert ist. Und zwar entweder nach dem Motto: „Mehr ist mehr“, bei dem die Hauptseite selbst entscheidet, welche Events relevant sind – oder es werden sehr zielgerichtet nur die Daten weitergegeben, die für das Tracking wesentlich sind. Welchem Ansatz zu folgen ist, hängt im Wesentlichen von zwei Faktoren ab:
- Was soll alles getracked werden?
- Was will der iFrame einer Hauptseite überhaupt „verraten“?
Die zweite Frage zielt darauf ab, dass in einem iFrame oft persönliche Daten eingegeben werden, die man auf der einen Seite – vielleicht – im Rahmen eines Tracking-Setups nutzen möchte (Stichwort „Enhanced Conversions“), auf der anderen Seite aber als Anbieter des Buchungsprozesses nicht zwingend mit der Webanalyse, Facebook und anderen Diensten teilen will, die auf der Hauptseite verbaut sein mögen.
Je nachdem, ob also z. B. ein kompletter dataLayer aus einem iFrame inkl. aller Klick-Ereignisse, auslösenden Visibility-Triggern und was sonst noch an die Hauptseite gemeldet werden soll oder ob es ausreicht, das Laden eines neuen Prozess-Schritts inkl. eines Erfolgs-Events am Ende einer Formularstrecke als Event zu vermelden und dabei ggf. punktuell weitere Attribute (Termindaten, Preise, Produkte o. Ä.) hinzuzufügen, kann die konkrete Implementierung des Nachrichtenversands im iFrame unterschiedlich komplex ausfallen. Das Mittel bleibt stets das Gleiche. Genutzt wird die postMessage API.
postMessage FTW!
Mittels postMessage kann ein iFrame mit der beinhaltenden Seite via JavaScript kommunizieren und dabei Nachrichten beliebiger Art versenden. Was im Fall von JavaScript bedeutet, dass einfache Variablen mit Zeichenketten oder komplexere Objekte bzw. Arrays von Werten versendet werden können. Ein „bookingSuccess“ als einfacher Event-Marker in einer Nachricht kann auf diesem Weg also genauso zur Hauptseite gelangen wie ein kompletter dataLayer-Push inkl. E-Commerce Daten (oder ein dataLayer als komplette Nutzlast der Nachricht).
Ein solcher Aufruf kann im einfachsten Fall so aussehen:
Neben der Nachricht selbst bestimmt der Versender zudem im zweiten Parameter, welche Domains die Informationen empfangen dürfen. Meint: Messages können entweder generell an alle ggf. vorhandenen den iFrame beinhaltenden Seiten (*) gelangen oder nur dann, wenn die Hauptseite auf einer Liste von Domains steht, die der Nachricht als mögliche Empfängeradressen an dieser Stelle mitgegeben werden.
Kontrolle auf beiden Seiten
Damit hat ein iFrame die komplette Kontrolle darüber, wer welche Informationen bekommt, wenn mit den Inhalten des iFrames interagiert wird. Hinzu kommt, dass die Nutzung dieser API nahezu in allen noch relevanten Browsern unterstützt wird. Und es gibt (derzeit noch) keinen Grund für einen Browser, diese Kommunikation zu unterbinden. Denn durch das Senden von Nachrichten allein kann ein iFrame keinen Schaden auf der Hauptseite anrichten. Damit mit den Messages etwas passiert, muss die Hauptseite diese aktiv auslesen und dann ggf. verarbeiten – oder ignorieren.
Das passiert i. d. R. über einen Event-Listener, der alle Message-Ereignisse verarbeitet, die die Hauptseite erreichen. Auch hier kann die Syntax denkbar einfach sein. Um z. B. alle empfangenen Nachrichten 1:1 und ungefiltert in den eigenen dataLayer zu übernehmen (um dann dort mit den Bordmitteln des Tag Managers Variablen, Trigger und Tags mit den Werten zu füttern) und dabei einen eindeutigen Event-Key wie „iFrameEvent“ zu nutzen, reicht dieser faktische Einzeiler, der als HTML Tag auf der Hauptseite ausgespielt werden kann:
if (!e.data) return;
//Verarbeitung. Hier: Übergabe an dataLayer
window.dataLayer.push(event: 'iFrameEvent', payload: e.data);
});
Diese beiden Codezeilen zum Versand bzw. dem Empfang und der Verarbeitung einer Nachricht sind freilich nicht für den Echtbetrieb ideal geeignet und werden i. d. R. etwas komplexer ausfallen. Das Prinzip braucht nur diese beiden Aufrufe zum Funktionieren.
Alle Nachrichten mit Daten, die dem Tracking dienen (oder zu anderen Zwecken der Hauptseite zufließen sollen), werden nach dem ersten Beispiel gezielt versendet und dort mit der zweiten Zeile empfangen und z. B. in den dataLayer übernommen oder auf andere Weise direkt verarbeitet.
Beispiele
Wie schon beschrieben ist es in den meisten Fällen sinnvoll, alle Events aus einem iFrame, die "lokale" dataLayer-Inhalte generieren, per Messages an die Hauptseite weiterzuleiten. Ein relativ komplexer Weg dazu ist im “Quasi-Standardwerk” zu diesem Thema bei Simo Ahava im Blog zu finden. Dabei dient ein GTM im iFrame dazu, die Kommunikation mit der Hauptseite herzustellen (hier sogar mit einem vorherigen “Handshake”-Prozess) und dann alle Ereignisse “nach oben” weiterzugeben, wo ebenfalls via GTM der Empfang und schlussendlich die Verarbeitung stattfindet.
Um das Prinzip zu demonstrieren, reichen zwei einfache lokal auf dem eigenen Rechner gespeicherte Seiten. Bei GitHub gibt es dazu einen Satz an Beispielen. Dabei werden Nachrichten von einer statischen inneren Seite im Fall von Button-Klicks etc. an die beinhaltende Hauptseite vermittelt. Beide protokollieren den Versand und Empfang in der Konsole des Browsers.
Der einfach gestaltete Empfänger kann verschiedene Typen von Nachrichten (einfache Daten wie Strings, komplexere Daten als Objekt oder JSON) verarbeiten und als Event / Nutzlast - Kombination im dataLayer ablegen. Eine Demo im Bewegtbild zu dieser Methode findet sich bei YouTube.
Auf dieser Basis ein Tracking in einem Tag Manager aufzubauen, das sich an die Consent Lage im Browser hält, ist hiermit genau so einfach oder schwierig, als kämen die Events im dataLayer direkt aus der Hauptseite bzw. der diese bereitstellenden Anwendung. E-Commerce, Buchungsprozesse, Klick-Events, Sichtbarkeit, Scrollverhalten, URL-Wechsel oder virtuelle Pageviews aus einer Single Page Application: All diese Dinge wandern problemlos aus dem iFrame in den Kontext der beinhaltenden Seite und das dort stattfindende Tracking.
Fazit
Wer bereits mit iFrames und deren Vermessung zu tun hat, wird einige der aufgezählten Probleme kennen… und ggf. punktuell Lösungen oder Verbesserungen herbeigeführt haben. In diesem Fall besteht möglicherweise kein Grund, das bestehende Setup jetzt anzupassen. Es ist jedoch davon auszugehen, dass mit fortlaufend angezogenen Daumenschrauben durch moderne Browser die Lücken immer größer werden, die klassische iFrame Tracking-Setups in den Daten hinterlassen.
Nimmt man die fehlende Kontrolle hinsichtlich des Datenschutzes dazu für alles, was im iFrame passiert, sollte es vor allem im Sinne von Anbietern für iFrame Prozesse im eigenen Interesse sein, ein gut konfigurierbares Message-System zu implementieren, welches als künftige erste Wahl für Tracking dienen sollte. Das macht es bereits nutzenden Websites leichter, das Tracking stabiler zu gestalten und dient für potenzielle neue Einsatzorte nicht zuletzt als wesentliches Feature. „Easy to Track“ ist vielleicht derzeit kein typischer Punkt auf einer Liste der Highlight-Features. Sollte es aber vielleicht - endlich - werden.