GTM-Guide: Wo muss ich den Container einbinden?

Sie kennen das vielleicht: Marketing und IT haben sich nach längerer Abstimmung darauf geeinigt den Google Tag Manager einzusetzen um das Tracking der eigenen Webseite voranzutreiben. Doch schon stehen Sie vor der nächste Fragestellung mit potentieller Diskussion: wo und wie muss der Google Tag Manager überhaupt genau eingebunden werden und warum?

Ein Google Tag Manager Konto ist erstellt und ein Container wurde angelegt. Jetzt muss dieser noch in die Webseite eingebunden werden. Das traditionelle Google Universal Analytics wird im Normalfall im <head>-Bereich oder im Footer, direkt vor dem schließenden </body>-Tag, eingebunden. Mit dem Google Tag Manager verhält sich das ein wenig anders. Google empfiehlt, den Google Tag Manager Code direkt nach dem öffnenden <body>-Tag einzubinden:

<body>
    <!-- Google Tag Manager -->
    <noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
    height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <script>(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),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-XXXXXX');</script>
    <!-- End Google Tag Manager -->

Doch warum ist das so? Um das herauszufinden nehmen wir den Code zunächst einmal ein wenig auseinander.

Der erste Teil des Tracking-Codes ist das <noscript>-Tag, welches den Browser veranlasst den Google Tag Manager per iframe einzubinden, wenn kein JavaScript aktiviert ist:

<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

Dieser Teil des Codes funktioniert nur innerhalb des <body>-Tags.

Der zweite Teil des Tracking-Codes ist das eigentliche JavaScript. Dieser sieht, etwas entzerrt, so aus:

<script>(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),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>

Bei genauerer Betrachtung des Codes erkennt man, dass der Google Tag Manager Container durch j.async = true; asynchron geladen wird. Das bedeutet, dass der Browser nicht erst warten muss bis der Google Tag Manager Container komplett geladen wurde bevor der Rest der Seite geladen wird. Das Laden des Google Tag Manager Containers blockiert somit nicht das Laden der Seite, sondern verzögert es nur geringfügig. Darum ist es sinnvoll, den Container so früh wie möglich zu laden, um möglichst alles was auf der Seite passiert von Beginn an tracken zu können.

Die Advanced-Version

Um das Script im <head>-Bereich, und somit möglichst früh, einzubinden, müssen die beiden Code-Teile getrennt und einzeln eingebunden werden:

<!doctype html>
<html lang="de-DE" prefix="og: http://ogp.me/ns#">
  <head>
    ...
    <script>(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),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-XXXXXX');</script>
  </head>
  <body>
    <noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    ...
  </body>
</html>

Inkl. DataLayer würde sich das entsprechend so gestalten:

<!doctype html>
<html lang="de-DE" prefix="og: http://ogp.me/ns#">
  <head>
    ...
    <script>(window.dataLayer = window.dataLayer || []).push({
        'variable': 'value'
    });</script>
    <script>(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),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-XXXXXX');</script>
  </head>
  <body>
    <noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    ...
  </body>
</html>

Offiziell wird das von Google Analytics nicht empfohlen. Das liegt jedoch daran, dass Google Analytics versucht die Einbindung auch für Nicht-Entwickler möglichst einfach zu gestalten und somit einen einzelnen Code-Block anbietet. Der Kompromiss dabei ist dann, diesen direkt hinter dem <body>-Tag zu platzieren.

Die Pro-Version

Diving deeper into GTM

Um die Einbindung des Google Tag Managers weiter zu verbessern, ist es zunächst wichtig genau zu verstehen was das Script eigentlich tut. Entzerrt sieht das Script so aus:

<script>
(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),
    dl = l != 'dataLayer' ? '&l=' + l : '';
    j.async = true;
    j.src= '//www.googletagmanager.com/gtm.js?id=' + i + dl;
    f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');
</script>

Den Zeilen 1 und 15 müssen wir keine größere Beachtung schenken, denn dabei handelt sich lediglich um die umschließenden HTML-Tags .

Zeile 2 und 14

(function(w,d,s,l,i){
    ...
})(window,document,'script','dataLayer','GTM-XXXXXX');

In Zeile 2 wird eine Funktion mit fünf Parametern erzeugt und direkt aufgerufen. Die Parameter werden in Zeile 15 übergeben, sodass diese Variablen innerhalb der Funktion bereitstehen:

  • (w) window: dieses Objekt enthält alles was im aktuell geöffneten Browser-Fenster enthalten ist
  • (d) document: das DOM-Objekt enthält den gesamten HTML-Code der Seite
  • (s) script: wird genutzt um später die Script-Bibliothek gtm.js zu laden
  • (l) dataLayer: der Name des dataLayer-Objekts; dieser ist standardmäßig dataLayer, kann jedoch beliebig umbenannt werden falls die Benennung mit anderen Scripts kollidiert
  • (i) GTM-XXXXXX: die ID des Google Tag Manager Containers

Zeile 3

    w[l]=w[l]||[];

In dieser Zeile wird geprüft, ob bereits ein Objekt mit dem Namen dataLayer existiert. Ist dies nicht der Fall, wird ein neues, leeres Array angelegt. Über diesen dataLayer werden später die Informationen von der Webseite, über den Google Tag Manager an Google Analytics übermittelt. Darum ist es wichtig, dass dieser Teil des Scripts so früh wie möglich auf der Seite ausgeführt wird.
Der Code sieht, mit Verwendung der in Zeile 14 übergebenen Variablen, dann so aus:

    window['dataLayer'] = window['dataLayer'] || [];

Zeilen 4 – 7

    w[l].push({
      'gtm.start': new Date().getTime(),
      event:'gtm.js'
    });

Hier werden nun die ersten Daten zum bereits angelegte dataLayer-Objekt hinzugefügt. Konkret werden hier zwei Variablen übergeben:

  • gtm.start: new Date().getTime()die aktuelle Zeit in Millisekunden seit 1. Januar 1970
  • event: gtm.jsdas Event auf welchem alle GTM-Trigger standardmäßig basieren ({{event}} equals gtm.js bzw. {{url}} matches regex .*)

Zeilen 8 – 13

    var f = d.getElementsByTagName(s)[0],
    j = d.createElement(s),
    dl = l != 'dataLayer' ? '&l=' + l : '';
    j.async = true;
    j.src= '//www.googletagmanager.com/gtm.js?id=' + i + dl;
    f.parentNode.insertBefore(j,f);

Zunächst werden hier alle Script-Elemente der Seite geladen (Zeile 8) und ein neues Script-Element erzeugt (Zeile 9).
Dann wird geprüft, ob das dataLayer-Objekt umbenannt wurde. Ist dies der Fall, wird ein Parameter für die Einbindung des Scripts vorbereitet (Zeile 10), welcher den geänderten Namen des dataLayer-Objekts übergibt.
In Zeile 11 wird angegeben, dass das Script asynchron geladen werden soll und in Zeile 12 die Source-URL zusammengesetzt, bevor in Zeile 13 das HTML-Element schließlich erzeugt und eingebunden wird.

Diese sechs Zeilen erzeugen folgenden Code:

    <script async src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXXX"></script>

Sollte sich Benennung des dataLayer-Objekts geändert haben, ändert sich der erzeugte Code und übergibt einen entsprechenden Parameter:

    <script async src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXXX&l=meinDataLayer"></script>

Insgesamt, lässt sich das, was zur Einbindung des Google Tag Manager Containers benötigt wird, auf drei Zeilen Code herunterbrechen:

    <script>(window.dataLayer = window.dataLayer || []).push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });</script>

Diese Zeile sollte so früh wie möglich eingebunden werden, sodass Daten im dataLayer-Objekt zwischengespeichert werden können.

    <script async src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXXX"></script>

Hier wird das eigentlich Script des Google Tag Managers aufgerufen. Auch diese Zeile sollte so früh wie möglich aufgerufen werden, damit das Tracking zu frühstmöglichen Zeitpunkt greift. Um den Seitenaufbau nicht merklich zu verzögern, sollte das Script allerdings erst nach der Einbindung der Stylesheet-Dateien erfolgen.

    <noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

Auch bei der Einbindung des Fallbacks, falls kein JavaScript aktiviert ist, ist es sinnvoll diese frühzeitig zu tätigen. Beachtet werden muss allerdings, dass diese unbedingt innerhalb des <body>-Tags erfolgen muss um zu funktionieren.

Die ideale Einbindung des Google Tag Manager Containers

Die ideale Einbindung des Google Tag Manager Containers sieht demzufolge so aus:

<!doctype html>
<html lang="de-DE" prefix="og: http://ogp.me/ns#">
    <head>
        <script>(window.dataLayer = window.dataLayer || []).push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });</script>
        ...
        <script async src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXXX"></script>
    </head>
    <body>
        <noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
        ...
    </body>
</html>

Inkl. DataLayer würde sich das entsprechend so gestalten:

<!doctype html>
<html lang="de-DE" prefix="og: http://ogp.me/ns#">
    <head>
        <script>
            (window.dataLayer = window.dataLayer || []).push({
                'gtm.start': new Date().getTime(),
                event: 'gtm.js',
                'variable': 'value'
            });
        </script>
        ...
        <script async src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXXX"></script>
    </head>
    <body>
        <noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
        ...
    </body>
</html>

Wie sieht die Einbindung bei Ihnen aus? Haben Sie bereits Erfahren mit unterschiedlichen Formen der Einbindung gesammelt?

Alle Beiträge von Dominik

Unsere meistgelesenen Beiträge

Zwei Jahre Chromebook: Ein Erfahrungsbericht

Google Chromebook
|
Gute 25 Jahre PC-Nutzung - von Anfang an mit Windows. Dann raucht im wahrsten Sinne des Wortes mein teures und gar nicht so altes Lenovo-Notebook ab. Und ich bestelle mir einfach ein Chromebook und bin schneller weg aus der Windows-Welt, als ich es für möglich gehalten hätte. Zwei Jahre ist das nun her - und ich habe zwischendurch immer wieder über meine Erfahrungen mit dem Chromebook berichtet.