When previewing Custom HTML tags in Google Tag Manager you’ve almost certainly run into a situation where the GTM variable shows up as a weird JavaScript method resembling something like this:
google_tag_manager[“GTM-ABCD123”].macro(15)
And this is when you were expecting it to show the actual, resolved value!
It doesn’t help that every now and then the preview mode actually shows to correct value in the preview mode.
What’s up with that? Well, there’s a fairly logical explanation to this. Read on!
X
The Simmer Newsletter
Subscribe to the Simmer newsletter to get the latest news and content from Simo Ahava into your email inbox!
Let’s start with the good news.
Your tag and the variables are most likely working as they should.
When you create a Custom HTML tag in Google Tag Manager, you are actually creating HTML elements that are appended to the end of the element when the tag fires.
This means that if the HTML element you are injecting is a function() {
var log = function(msg) {
if ({{Debug Mode}}) {
console.log(msg);
}
};
log({{Some Variable}});
window.someFunction({{Some Variable}});
})();
]]>
In the code sample above, there is a global method window.someFunction to which we want to pass the variable {{Some Variable}}. However, we are uncertain what its actual value is since Preview mode isn’t very helpful.
Because of this, we log the value of {{Some Variable}} into the browser JavaScript console.
Furthermore, I’ve built a helper function named log() that only logs the value to console if GTM is in Preview mode. This way you avoid your tags from writing arbitrary log messages into the live browser console.
3. Debug the tag result
This is the most difficult way to debug whether or not the variable worked. Unfortunately, it’s also the best way to do it.
When you add JavaScript to a Custom HTML tag, it should do something. Maybe it adds some text to an HTML element, maybe it creates a new pixel or Ajax call, or perhaps it pushes something to dataLayer.
In any case, the best way to ensure whether or not the .macro() call resolved to its correct value is to check the output or result of the tag itself to see if whatever value the variable was supposed to pass was done correctly.
For example, let’s say your tag creates a pixel request like this:
<script>
(function() {
var imgId = ‘?id=’ + {{Container ID}};
var imgUrl = ‘https://www.somedomain.com/img’ + imgId;
var el = document.createElement(‘img’);
el.src = imgUrl;
document.body.appendChild(el);
})();
script>
It’s a simple, almost nonsensical example, but it should serve to highlight the debug process nicely.
The tag creates a new image element whose URL is https://www.somedomain.com/img plus the string ?id= concatenated with whatever is returned by the {{Container ID}} variable.
This is what it looks like in Preview mode:
This is what it looks like after injection in the Inspect Elements pane:
Note! As you can see, in Inspect Elements the script element still has the .macro() call. This is how the browser works. GTM injected an element with the .macro() call and this is what was added to the page. If you remember, the script isn’t executed until AFTER injection.
Finally, you can inspect the Network Requests to find the image request with the ID in place.
Also, because the tag did its own little injection with document.body.appendChild(el), you can find the image element at the end of by inspecting the elements on the page.
Summary
I hope this article has alleviated your concerns. If you see a call to .macro() in Google Tag Manager’s Preview mode, don’t worry. It’s what you’re supposed to see.
GTM will not resolve variables until the Custom HTML tag has been injected at the end of and the browser has begun to render any JavaScript between and within the Custom HTML tag.
The main exception is variables cast into strings, which Google Tag Manager will have to resolve before injection or else it will end up casting the function expression itself into a string which is not helpful.
Hopefully this article is helpful in offering you a number of ways you can debug those pesky .macro() calls just to be sure that things are working as they should.
Let me know if you’ve run into edge cases where it still doesn’t work, or if you have other examples in addition to cast strings where GTM resolves the variable in Preview mode.