There are times when I’m disappointed with Google’s developer documentation, especially for Google Tag Manager. Most of the time they get it right, and I’d say around 80% of questions being thrown around the forums can be answered just by reading through the documentation. But there are some cases where the documentation is misleading or even downright dangerous. One of these cases is Enhanced Ecommerce.

This isn’t going to be a thorough critique of said documentation, but the tip in this post has to do with one of the examples that the documentation gives for measuring Product Clicks. In the comment it says:

...This function uses the eventCallback dataLayer variable to handle navigation after the ecommerce data has been sent to Google Analytics...

Well, that’s an excellent use case for eventCallback. After all, it’s sole purpose is to execute code after all Tags have completed for the given event in the dataLayer.push payload.

However, the pain point here is that you’re using Google Tag Manager to defer a crucial, potentially UX- and business-hurting action: the link redirect. The point of the example is that the link redirect is cancelled, and only once the eventCallback is invoked will the redirect continue.

That, my friends, is not a good pattern.

If any of the Tags that fire on this payload fail, timeout, or in some other way fail to inform GTM that they have completed, the redirect will never happen, and the user is left confused since the link they’re trying to click doesn’t work.

IMPORTANT UPDATE, 5 Jan 2018: Firefox’s latest update to its Tracking Protection in Private Browsing now blocks Google Tag Manager, too. So even setting eventTimeout won’t help. My suggestion is to not cancel clicks outside Google Tag Manager with the intention of doing the redirect via some Google Tag Manager -related method, such as eventCallback. (Update over).

This is especially important in the recent versions of the Firefox web browser! Firefox introduced something called Tracking Protection in Private Browsing a while ago, and one of its features is that it blocks Google Analytics from loading on the page. However, it does not block Google Tag Manager. In other words, Google Tag Manager loads, the dataLayer.push() is processed and everything, but if there’s even a single Google Analytics Tag with a dependency on the push, the eventCallback function is never called.

To fix this, here’s a tip:

Tip 48: Always add eventTimeout when you use eventCallback

Always add the eventTimeout when using eventCallback. The former takes a numerical value as its parameter, representing the number of milliseconds to wait before calling eventCallback anyway. In other words, even if your Tags stall and never signal completion, after two seconds eventCallback is invoked.

So, let’s imagine you have this, problematic code:

var processLinkClick = function(e) {
  e.preventDefault();
  var targetUrl = e.target.href;
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    'event' : 'processLink',
    'eventCallback' : function() {
      window.location = targetUrl
    }
  });
};

It’s a function which grabs the event object, prevents its default action (redirect), does the dataLayer.push(), and finally in the eventCallback finalizes the redirect. But there’s no safeguard a) for when Google Tag Manager isn’t loaded, and b) if the Tags stall.

So here’s the fixed code:

var processLinkClick = function(e) {
  var targetUrl;
  if (window['google_tag_manager']) {
    e.preventDefault();
    targetUrl = e.target.href;
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      'event' : 'processLink',
      'eventCallback' : function() {
        window.location = targetUrl
      },
      'eventTimeout' : 2000
    });
  }
};

As you can see, we’re now also checking for the existence of google_tag_manager, which is the interface created by the gtm.js library when it is executed. So if the Google Tag Manager library isn’t loaded, the dataLayer.push() is never executed. Sure, there might be a race condition where the library is still in the process of being loaded, but there are ways to mitigate this, too.

Finally, the eventTimeout introduces a timeout of two seconds, after which the redirect is done. Thus even if any Tags that fire on the “processLink” event stall, the redirect is not blocked.

I hope this tip was useful to you! There are many instances where you really need to be careful that you Google Tag Manager setup isn’t killing the usability of your website. This is one of them.