Google Tag Manager

Aufbau

Toast

Laden des JavaScripts über Toast.

toast(
    "[css]'css/application.css'",
    function () {
        // Aufruf, falls CSS ready
    },
    "[js]'js/application.js'"
);

Queue

Die Queue ist unsere Bezeichung für die Warteschlange zum Abarbeiten von Anfragen und wird als Benutzerdefiniertes HTML-Tag im Google Tag Manager implementiert. Die Queue bildet das "Herzstück" für die Remarketing- und Conversion-Tags, um mit den Marketing-Ma0nahmen und Erfolgsmessungen die Performance der Website für die Besucher nicht zu beeinträchtigen.

etracker

Das Webanalyse-Tool etracker bietet trotz Neuerungen des User-Interfaces nach wie vor lediglich einen synchronen Code zum Einbinden an.

<!-- Copyright (c) 2000-2016 etracker GmbH. All rights reserved. -->
<!-- This material may not be reproduced, displayed, modified or distributed -->
<!-- without the express prior written permission of the copyright holder. -->
<!-- etracker tracklet 4.1 -->
<script type="text/javascript">
	//var et_pagename = "";
	//var et_areas = "";
	//var et_url = "";
	//var et_target = "";
	//var et_tval = "";
	//var et_tonr = "";
	//var et_tsale = 0;
	//var et_basket = "";
	//var et_cust = "";
</script>
<script id="_etLoader" type="text/javascript" charset="UTF-8" data-secure-code="XXXXXX" src="//static.etracker.com/code/e.js"></script>
<!-- etracker tracklet 4.1 end -->

Zum Vergleich: asynchoner Tracking-Code von Google Analytics

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-12345678-9"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag("js", new Date());

  gtag("config", "UA-12345678-9");
</script>

Wird dieser nun in einen asynchron geladenen Tag Manager implementiert, kann es zu sogenannten Timing Issues kommen: Soll beispielsweise mit dem Aufruf einer Anmeldebestätigung (Aufruf Danke-Seite) zeitgleich eine Conversion erfasst werden, feuert der Tag Manager das Event, noch bevor der Seitenabruf fertig initialisiert und bereit ist. Die Folge: der Seitenaufruf wird gezählt, die Conversion nicht.

Die Lösung, wenn auf die Vorteile einer asynchronen Einbindung nicht verzichtet werden soll, heißt Queue: eine Warteschlange, welche die Events "zwischenparkt" und erst dann weitergibt, wenn etracker fertig geladen und bereit ist.

Remarketing

Wenn die Queue sowieso schon mit dem JavaScript Core steht, kann sie auch für Remarketing- und Conversion-Tags verwendet werden. Mit der Einbindung über Toast und die Queue ziehen die Tags auch den oft als KPI verwendeten Google Page Speed Index nicht in Mitleidenschaft. An dieser Stelle wollen wir aber noch einmal betonen: ein guter Page Speed Wert entscheidet nicht allein über eine performante Seite. Jedoch wird damit sichergestellt, dass die wichtigen Elemente (also die Inhalte der Seite) früher geladen werden und bereit stehen – und die Remarketing-Tags hinten angestellt werden und die persönliche Empfindung einer schnell ladenden Website nicht beeinträchtigen.

Übergreifende und individuelle Google Tag Manager Container

Ein Problem beim professionellen Arbeiten mit dem Google Tag Manager ist das Management von verschiedenen Versionsständen und das Ausrollen neuer Features auf eine Vielzahl von Tag Manager Containern. Mit Werkzeugen wie den GTM Tools von Simo Ahava fällt das Übertragen zwar leichter, bringt aber immer noch Schwierigkeiten beim Nachziehen von Änderungen mit sich.

Die Tags und Trigger für ein Tracking sind beim Einsatz von gleichen Systemen, beispielsweise beim Einsatz einer WordPress Multisite-Installation, in der Regel identisch. Die Variablen (Analytics- und Conversion-IDs, Piwik- oder etracker Secure-Code usw.) unterscheiden sich natürlich von Seite zu Seite. Da diese aber über Suchtabellen (ein Variablen-Typ im GTM) pro Website individuell ausgespielt werden können, steht dem Einsatz eines Konstrukts mit übergreifendem und individuellen Containern oftmals nichts im Weg.

Übergreifender Container

Ein übergreifender Container bezeichnet einen Google Tag Manager Container, welcher auf einer Vielzahl von Websites (also Seiten mit unterschiedlichen Domains) eingebunden wird.

Unsere Voraussetzungen und Empfehlungen für ein solches Setup:

  • Der technische "Unterbau" der Webseiten ist pro Container gleich. Das ist z. B. der Fall, wenn das gleiche CMS (z. B. WordPress, Drupal oder Magento) eingesetzt wird.
  • Das Tracking darf zu gleichen Zeiten verbessert bzw. modifiziert werden (eine Änderung von mehrfach verwendeten Tags im Container betrifft i. d. R. dann auch alle Websites und Analyse-Systeme).
  • Die Webanalyse- und Conversion-IDs der jeweiligen Websites können mit Integrationstests (halb-)automatisiert überprüft werden.
  • Umfangreiche und individuelle Remarketing- und Conversion-Tags werden über einen zweiten Tag Manager Container implementiert.

Der erste GTM-Container verwaltet das standardisierte Tracking (das für alle Websites auf gleiche Art und Weise erfolgen soll) und die Auslöseregel für die individuellen, zweiten Container (also ob, und wenn ja welcher Container bei einer Seite zusätzlich vorhanden sein soll). Alles, was nicht auf mindestens zwei oder mehr Web-Auftritten zum Einsatz kommen soll, wird in den individuellen zweiten Google Tag Manager Container einer Website ausgelagert.

Schaubild Google Tag Manager Konten und Container
Das Tracking für alle drei Seiten werden über den allgemeinen Container abgewickelt, das Remarketing (im Beispiel nur bei A und C gewünscht) über individuelle Zweit-Container, welche ebenfalls mittels übergreifendem Container ausgelöst werden. Im Quelltext der Websites A, B und C steht also nur der GTM-Code des allgemeinen Containers.

Individueller zweiter Container

Im individuellen Container gibt es im Idealfall keine Tags, welche für das Tracking der Seite verantwortlich sind (diese liegen alle im übergreifenden). Außnahme: ganz spezielle Tracking-Events, welche es nur auf dieser Seite geben soll.

Remarketing- und Conversion-Tags, welche sehr spezifisch auf einzelnen Seiten bzw. mit komplexen Auslöseregeln implementiert werden müssen, landen in diesem individuellen Container. Das können beispielsweise ID-basierte Conversion-Pixel sein, welche pro bestimmter Unterseite eine eigene Conversion-ID übermitteln. Diese können über Variablen als Suchtabellen angelegt sowohl für den Trigger wie auch für den Conversion-Tag verwendet werden.

Testen

Unit-Tests

Die Wichtigkeit von Unit-Tests wurde schon ausführlich im Artikel über die Entwicklung mit Symfony beschrieben. So wie PHPUnit unser Werkzeug der Wahl ist, wenn es um das Testen von PHP-Code geht, so bietet die Kombination aus Karma und Jasmine ganz ähnliche Möglichkeiten, um JavaScript-Code zuverlässig abtesten zu können.
Das folgende Code-Beispiel zeigt einen einfachen Jasmine-Test der Funktion addElement() der Klasse Queue:

describe("Queue model", function () {
    let mockQueue;

    beforeEach(function() {
        mockQueue = new Queue();
    });

    it("expect count to be one when added one element", function() {
        mockQueue.addElement({
           "eventObject": "https://www.google.de",
           "eventType": "download"
        });
        expect(mockQueue.count()).toBe(1);
        expect(mockQueue.getElement(0)).toEqual(Object({
            eventObject: "https://www.google.de", eventType: "download"
        }));
    });
});

Der Test erwartet, dass nach dem Ausführen von addElement() genau ein Element in der Queue gespeichert wurde.
So ähnlich werden auch alle anderen Klassen und Funktionen unserer Anwendung getestet.

Integrationstests

Der Begriff Integrationstest bezeichnet eine aufeinander abgestimmte Reihe von Unit-Tests, die dazu dienen, verschiedene voneinander abhängige Komponenten eines komplexen Systems im Zusammenspiel miteinander zu testen. Für uns bedeutet das, dass wir konkret die jeweiligen Seiten testen, auf denen der Google Tag Manager eingebaut wurde. Dabei kann durch eine entsprechende Konfiguration von Karma die Funktionalität in unterschiedlichen Browsern (PhantomJS, hrome, Firefox, Edge usw.) und auf unterschiedlichen Arten von Geräten (Desktop, Tablet oder Smartphone) getestet werden. Statt Jasmine benutzen wir für die Integrationstests Webdriver I/O. Die Funktionsweise eines solchen Integrationstests zeigt der folgende Beispielablauf.

Testablauf

  • Test-Browser wird im Hintergrund gestartet.
  • Die zu testende URL wird aufgerufen.
  • Es wird geprüft, ob JavaScript-Fehler auftreten (dieser Test funktioniert derzeit nur im PhantomJS-Browser):
    it("expect no JavaScript error", () => {
        let jsErrors = [];
        let errorMessages = [];
        jsErrors.forEach(error => errorMessages.push(error.message));
        let allowedJsErrors = page.allowedJsErrors | 0;
        expect(jsErrors).to.have.length(allowedJsErrors, "array of javascript errors must be empty, but found " + jsErrors.length + " error(s):\r\n" + errorMessages)
    });
  • Es wird geprüft, ob der richtige Tag Manager eingebunden wird:
    if (typeof site.gtmCodes !== "undefined") {
        site.gtmCodes.forEach(gtmCode => {
            it("expect GTM-Code '" + gtmCode + "'", () => {
                let gtmArray = Object.keys(getWindowVariable("google_tag_manager"));
                expect(gtmArray).to.include(gtmCode, "GTM-Code not found in google_tag_manager array keys '" + gtmArray + "'");
            });
        });
    }
  • Prüfung weiterer window-Variablen

Bei dieser Art von Tests ist die korrekte zeitliche Abfolge entscheidend. Denn ein Test auf das Vorhandensein eines Objekts würde fehlschlagen, wenn dieses vor dem eigentlichen Initialisieren dieses Objektes aufgerufen würde.

before(() => {
    browser.url(site.baseUrl + page.path).waitForVisible("body", 2000);
});

Diese "Timing Issues" können durch den Einsatz der Methode waitForVisible im before-Bereich gelöst werden. Der Code zwischen den Funktionsklammern wird vor allen anderen Tests ausgeführt, damit sichergestellt ist, dass der Body der Seite fertig geladen wurde und die anschließend folgenden Tests darauf zugreifen können.

Erste Erfahrungen

Das vorgestellte Setup fahren wir – je nach Kunde leicht unterschiedlich – seit mehreren Wochen bzw. Monaten:

  • deutliche Arbeits-Erleichterung beim Verbessern des Trackings für viele Websites (Konzept übergreifende und individuelle Container)
  • schnelle Ladezeiten trotz des Einsatzes mehrerer Trackingsysteme, Remarketing- und Conversion-Tags (Toast-Queue)
  • Sicherheit, dass einmal implementierte Tags auch nach einem Umbau immer noch vorhanden sind und korrekt in den richtigen Account feuern (Integrationstests)

Der Haupt-Aufwand war sicher die initiale Implementierung der Konstrukte mit übergreifenden und nachgelagerten Container, die Queue mit der Toolbar und das Schreiben der Integrations-Tests. Doch die Umsetzung spart im Alltag wertvolle Zeit und sichert dem Kunden das gewünschte Tracking. Projekt gelungen, Fortsetzung folgt.