(UPDATE 28 Sep 2016: The official recommendation has finally caught up with the times. Now the correct placement for the JavaScript methods of the container snippet is, indeed, in <head>.)

I want to address something I’ve been confused about from the very first day since I started using Google Tag Manager. Why on earth would an asynchronously loading JavaScript library be recommended to place in the beginning of <body>, when the logical place to start loading dependencies is as early as possible in the document load process? Well, the main reason for this is that the GTM library makes modifications to the document object model of the page in such a way that might cause conflicts when using Internet Explorer 7 or older.

Another reason is that the <iframe> within the <noscript> block is not valid HTML, which is a legitimate concern.

The third reason, which isn’t really a reason but rather an offshoot of the original Google Tag Manager recommendation, is that Google’s Search Console verification requires that the container snippet be embedded in the beginning of <body>.

In this post, I’ll tackle these three “issues” and wrap up with a consolation note that yes, it’s perfectly fine to add Google Tag Manager to the <head> of the document, and it might even be preferable to do so.

X

The Simmer Newsletter

Subscribe to the Simmer newsletter to get the latest news and content from Simo Ahava into your email inbox!

Tip 36: Add the GTM Container Snippet to <head>

Now, the possible conflicts arising with Internet Explorer 7 and older are easy to dismiss. Just forget those users! Punish them for using an antiquated version of the web browser. Honestly, Internet Explorer 7 is being used by 0.1% of Internet users, and that ratio is only going to go down. Do not weep for the lazy. Make them suffer in the hopes of inspiring them to upgrade or, preferably, change to some other brand of web browser.

Now, one thing you will have to do is remove the <iframe> element from the container snippet, since that’s just not valid HTML. An <iframe> is embedded content, and in HTML5, embedded content is never allowed in the <head> of the document. However, you don’t need to remove it entirely. Just copy-paste the entire <noscript> in the beginning of <body> if you’re concerned about your non-JavaScript users.

  <!-- Google Tag Manager -->
  <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 -->
</head>
<body>
  <noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

Simple solution for dealing with the validation problem.

Finally, the Search Console validation issue is a pain. There’s nothing you can do about that. If you choose to move the container snippet to the <head> of the document, you will need to use some other means of validating your site.

Why do it?

Sometimes you don’t have an option. WordPress themes, for example, rarely have a hook for adding code to the beginning of <body>, and you’ll need to hack around that by modifying the child templates. In these cases, adding the library to the <head> can save a lot of time and effort.

Also, remember that Google Tag Manager is an asynchronously loading library. This means that it’s loading as the page renders, and it’s non-blocking. Thus, the earlier you start loading the library, the more chance your Tags will have to fire and complete before the user leaves the page or closes the browser. This might result in a slight increase in data collection accuracy and quality.

As soon as the Search Console validator relaxes a little, I see little reason why you shouldn’t always add the container snippet to the <head> of the page. In fact, if we ever get a synchronous version of the container (for running e.g. A/B tests), adding the snippet to the <head> becomes a necessity.