Custom HTML Tags Sequencing in Google Tag Manager

Tag sequencing is a feature available in Google Tag Manager for quite a while, being introduced for the first time back in 2015. In a nutshell, tag sequencing enables you to specify tags to fire immediately before or after a primary tag is fired.

Since gtm.js loads asynchronously it means that it does not block other elements from rendering on the page and also does not allow slow loading tags to block other tracking tags. The drawback however, is that you have no control over the order that your tags fire. Tags with the same triggering event will all fire at the same time, but can complete in any order. Because of that, tag sequencing is quite useful when you want to create configurations with custom firing sequence separate from the normal flow in GTM.

Behind the scenes, everything happens with the help of a callback function. It really makes sense, as that is exactly what callback functions are used – to be called when something happens, i.e. code state changes. With the templated tags in GTM, there is not much to consider around callback really, as that functionality is built-in and you can just use it via the configuration of the particular tag template. The way it works in the background is by onSuccess callback is being pushed once the primary tag finishes, which allows the sequenced tag that you configured to fire after the primary tag.

It gets a bit trickier with Custom HTML Tags because they will not push onSuccess or onFailure callbacks once they complete execution. That means that the Custom HTML Tag won’t provide an identification to other tags that it completed execution. The solution to that problem is to push the onHtmlSuccess or onHtmlFailure callback methods yourself, via the code executed in the Custom HTML Tag.

Recently, I had to configure an Event Tag to send an event data to Google Analytics, after a Custom HTML Tag completes successfully. Additionally, the Custom HTML Tag’s functionality was to update the value of a cookie, and that value of the cookie had to be captured as a custom dimension and sent to Google Analytics with the Event Tag. As you can see the complexity is already there and the exact order of operations was needed.

In order to do that, I had to re-structure the code in the Custom HTML Tag in the following way:

<script>
  (function(window) {
    var googleTagManager = window.google_tag_manager[{{Container ID}}];
    try {
      // Custom HTML Tag code goes here
      // Notify GTM that HTML Tag finished successfully
      googleTagManager.onHtmlSuccess({{HTML ID}}); 
    } catch(e) {
      // Notify GTM that HTML Tag failed
      return googleTagManager.onHtmlFailure({{HTML ID}}); 
    }
  })(window);
</script>

The code above essentially executes the code that I had in the Custom HTML Tag, but wraps it up in a JavaScript – try…catch blocks, referencing the GTM Container and depending on the status of the code’s execution, pushes the mentioned above callback methods.
{{Container ID}} and {{HTML ID}} used in the code are built-in variables that had to be added from Google Tag Manager’s interface first in order for the code to work.

Based on my experience, there are cases, depending on how the code for the Custom HTML Tag is written, you can get some errors thrown from Google Tag Manager. In my case, I had this one in particular:

Error at line X, character X: this language feature is only supported for ECMASCRIPT6 mode or better: block-scoped function declaration. Use –language_in=ECMASCRIPT6 or ECMASCRIPT6_STRICT or higher to enable ES6 features.

I got that error thrown because before GTM wraps the code into a minimized JavaScript file to inject it into the page, the code goes through a linter. Google set rules for the linter that make it more strict and specifying the type of function declarations is something to be considered.

As you can see, I got that problem because the in main code for the Custom HTML Tag I had a function declared inside an if/else block. I that case, simply by changing how the function is declared fixed the problem. For instance, changing function myFunction(x,y){} to var myFunction = function(x,y){}.

With all of the above in place, the configuration that was required worked out nicely and the order of execution was on point.

To conclude it all, tag sequencing is quite a powerful feature of Google Tag Manager, and when you are aware of what happens behind the scenes and consider the few caveat and common erros, you can do quite a lot with it and have the power to execute tags in the order that meets the data capturing requirements.

Here are some useful resources for concepts/features referenced in this post:

Google Tag Manager – Tag sequencing
Google Tag Manager – How the Asynchronous Syntax Works
Google Tag Manager – Built-in Variables – Utilities
JavaScript – Callback Function
JavaScript – try…catch blocks

Share this Post

Leave a Reply

Your email address will not be published. Required fields are marked *