Tag sequencing was introdced to Google Tag Manager in late 2015. Its main purpose was to facilitate the sequential firing of tags that have dependencies with each other. Due to the asynchronous nature of third-party libraries like Google Tag Manager, it’s difficult to establish an order of completion with tags that compete for their chance to fire.

Tag sequencing changed this, as it allows you to establish setup and cleanup tags - the former firing before the main tag, and the latter after.

Setting up tag sequencing is relatively easy, at least once you understand how it works. However, Custom HTML tags have some exceptional behavior, as you need to utilize certain specific commands to signal the sequence once the Custom HTML tag has completed its execution. This #GTMTips article aims to guide you with setting up Custom HTML tags in a tag sequence.

Tip 83: Setting up Custom HTML tags in a tag sequence

Lesson 1: Sequence is managed with the success and failure callbacks

The two callbacks, onHtmlSuccess() and onHtmlFailure() are what tag sequencing with Custom HTML tags really pivots around. The first is used to denote a place in the code when the code has finished running successfully, and execution can move to the next tag in the sequence. The second is used to signal when a failure happens, and here execution is also passed to the next tag in the sequence unless it has the failure toggle on:

Just to recap (but be sure to read my guide for a more thorough treatment), here’s how you would set up a regular Custom HTML tag in a tag sequence, where both success and failure criteria are established.

NOTE! Remember to enable the Container ID and HTML ID built-in variables for this.

(function() {
  var gtm = window.google_tag_manager[{{Container ID}}]; // Required
	  
  window['something'] = getSomethingElse();
  if (typeof window['something'] !== 'undefined') {
    gtm.onHtmlSuccess({{HTML ID}}); // Success, move to next tag
  } else {
    gtm.onHtmlFailure({{HTML ID}}); // Failure, move to next tag unless it has failure toggle on
  }
})();

Lesson 2: The success and failure callbacks aren’t always necessary

Here’s something I think most guides have missed: you don’t need onHtmlSuccess() and onHtmlFailure() in your Custom HTML tag! The web browser executes all the code it finds in a Custom HTML tag from top-to-bottom before moving to the next item in the sequence.

For example, if you’ve setup the Facebook pixel with Custom HTML tags, you don’t need onHtmlSuccess() in the base pixel tag.

!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
 
fbq('init', {{Facebook Pixel ID}});

// The following line is NOT necessary:
// window.google_tag_manager[{{Container ID}}].onHtmlSuccess({{HTML ID}}); 
Why is the last line not necessary? Because GTM would pass execution to the next tag in any case when it reaches the last line of this tag. The web browser runs code synchronously - there’s no way it will stop in the middle of this tag and start working on the next tag.

So the lesson is:

If you have code that is always run from top-to-bottom before moving to the next tag, you don’t need onHtmlSuccess() and onHtmlFailure().

But, and there’s always a “but”, you’ll want to check the next lesson, too.

Lesson 3: If you have onHtmlFailure(), you’ll always want to have onHtmlSuccess(), too

If you use onHtmlFailure() to signal that at some point in the code an error is met and sequence should not proceed with the next tag (since you have the failure toggle on), you should also add onHtmlSuccess() somewhere in the code.

This is because when you use the failure callback, GTM will not automatically proceed to the next tag anymore when it reaches the last line of the Custom HTML tag, even if you have the failure toggle turned off. By using onHtmlFailure(), you are telling Google Tag Manager to wait for either the onHtmlFailure() or onHtmlSuccess() before deciding whether to move to the next tag.

(function() {
  var gtm = window.google_tag_manager[{{Container ID}}];
  
  if (true) {
    console.log('Worked!');
  } else {
    gtm.onHtmlFailure({{HTML ID}});
  }
})();

In the above example, sequence will never proceed to the next tag. You have onHtmlFailure() which is never met (because true is always true), but you don’t have onHtmlSuccess() anywhere. So only this first tag is run, and the sequence is never continued.

This is one way it would work:

if (true) {
  console.log('Worked');
  gtm.onHtmlSuccess({{HTML ID}});
} else {
  gtm.onHtmlFailure({{HTML ID}});
}

This would also work (though it’s not a good pattern), if the next tag in the sequence had the failure toggle off:

if (true) {
  console.log('Worked');
  gtm.onHtmlFailure({{HTML ID}});
} else {
  gtm.onHtmlFailure({{HTML ID}});
}

And since it’s synchronous code, you can leave both callbacks out, and the sequence will proceed normally after logging Worked to the console in this case, too:

(function() {
  if (true) {
    console.log('Worked');
  }
})();

Lesson 4: The callbacks are at their best in asynchronous operations

In my view, the purpose of tag sequencing is to establish order when the previous tag has an asynchronous operation. In other words, you want the browser to wait for the operation to complete before telling the next tag to start firing.

For example, here we load the jQuery library asynchronously, waiting for it to have completely loaded before moving to the next tag:

(function() {
  var gtm = window.google_tag_manager[{{Container ID}}];
  
  var el = document.createElement('script');
  el.async = true;
  el.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js';
  el.addEventListener('load', function() {
    gtm.onHtmlSuccess({{HTML ID}});
  });
  document.head.appendChild(el);
})();

As you can see, onHtmlSuccess() is embedded in the callback of the load listener, which is invoked only after the library has downloaded and the browser has executed the code within.

Summary

Working with Custom HTML tags in a tag sequence has some gotchas you should be aware of, but there’s really very little game-breaking. The biggest “mistake” I see people doing is adding the onHtmlSuccess() callback to the end of a synchronously executed block of code - this is not necessary unless you have onHtmlFailure() somewhere in the code, too.

I hope that this article has clarified how Custom HTML tags and tag sequencing work together.

Let me know in the comments if you have futher questions!