got some questions about the Google Tag Manager snippet. If I'm looking at the Google Demo Shop website the GTM implementation is like this :
<head>
<script async="" src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXX"></script>
... some stuff ...
<noscript> <iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXX" 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-5Q5LZH');
</script>
</head>
So basically everything is in the header. So first question, what is this line for :
<script async="" src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXX"></script>
Second question, I've read that the code below:
<noscript> <iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXX" 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-5Q5LZH');
</script>
could be implemented just after the opening of the body tag... and I've seen this a lot.
Is there some real differences between these different kind of implementation ? It doesn't seems to make any differences for Google Tag Assistant. Thanks !
Initially Google Tag Manager recommended that the GTM snippet be located in the <body>
, however it has recently updated its recomendation for it to be in the <head>
.
This is most likely due to two reasons.
1) Apparently there were concerns about the way that the GTM library made modifications to the document object model which might have lead to conflicts for IE7 or older.
2) The <iframe>
within the <noscript>
is embedded content, rather then HTML, which is not allowed in the <head>
of the document.
Recently Google has updated its guides and documentation to show a split implementation, with the in the <script>
in the <head>
and the <noscript><iframe>
in the <body>
.
This makes sense, as there is no reason why an asynchonrous JavaScript library needs to be in the <body>
. As with all tracking its ideal to have the dependencies loaded as early as possible to ensure that your tracking is available prior to the user interacting with the website. However due to reason 2, the <noscript><iframe>
is still recommended to be placed in the <body>
.
So, to answer your questions:
1) the implementation on the Google Demo Store is incorrect, the entire code should not be placed in the <head>
.
2) The <script async="" src="//www.googletagmanager.com/gtm.js?id=GTM-XXXXX"></script>
in the Tag Assistant is not the actual code, but how the Tag Management extension interprets the code.
3) The <body>
implementation was the previously recommended implementation, which is why you have seen it a lot.
4) Going forward, I would recommend the implementation advised by Google when setting up a Google Tag Manager container, spiting the placement between the <head>
and the <body>
. This means that GTM will load as early as possible, with an iframe backup if required.
5) Tag Assistant merely checks the code against rules manually set within the extension. The obvious caveat of this is that the extension needs to be kept up to date. An example of this is that recently the GTM container id's moved from 6 to 7 characters however the extension was not updated, leading to a lot of people getting errors in the Tag Assistant stating that their container ID was incorrect.