Tips for working with Custom HTML & Custom JavaScript tags in Google Tag Manager

This time I'm writting down some tips for when you guys are playing around with the custom HTML tags or custom JavaScript variables not only for Google Tag Manager, but for any other TMS or website.

Most times due the projects deadlines or maybe just lazyness, the code we use (I include myself here), is not fail proof, and we need to think that we may broke some page functionality or even some page load. So using customHTML/custom JavaScript is a serious thing. Even a lot of companies are forbidden to use them in Google Tag Manager.

  1. Don't use lazy/generic variable names

    As you all know (right) all the scripts share the same window object. So if you declare a variable

    myVariable = "myValue";

    you will then be able to get that variable value from the main window object


    and this means that if we using some variable like "counter", and another script uses it, it's going to be overrided. D'oh, our loop just became a neverending loop (indeed, that's not good).

  2. Always use "var" for declaring your variables if you are not planning to use them as a global data

    Usually you may think that declaring a variable inside a function will make it just available inside that function, but that's not right, if you declare a variable without using "var", it's gonna became a global variable, if you want to try it, create a new tag an put this code on it:

    <script> (function(){ myVariable = "myValuetest"; })();</script>

    Now if you go to your console you will notice that windows.myVariable is there. Even if it was inside anonymous function, it became a global variable.

    This is the right way to do it:

    <script> (function(){ var myVariable = "myValuetest"; })();</script>
  3. Always check for the variable value before doing something with it

    Usually being a lazy programmer will lead to problems, I know that it takes a lot of time to get everything checked as it should, and our code may be working for us in our tests, but we need to think that there will be thousands of users, with different browsers, browser versions, internet connections (some things may load slow, or not even load) , pluggins installed, and that's why we need to perform the checks in the right way, we're interacting with a client-side tracking, so we just CAN'T cover all the possible situations.

    Take this simple screenshot as an example:

    Let's see how should we had code the previous snippet:

    Instead of printing an error, we could have send an error event, in order to track on which pages that errors is happening, for which browsers, or at which time :)

  4. Be careful with the loops, always set a break in the case the condition is never met

    We may need to loop around some array, for example, we want to grab all the product SKU for our transactions to pass that data into a marketing pixel. For that we'll need to loop thru all the ecommerce.purchase.products . but we need to be sure that our loop will end at some point. For the previous example it's easy, as we'll easily know when it needs to end (when there're no mor products in the array).
    But let's think on another example. We want to wait for some object to be available to fire something, and for that we use a setInterval to check for the variable availability each 100 milliseconds.

    Let's see some code for this:

    (function(){var checkExist = setInterval(function() { if(typeof(window.myObject)!="undefined") { dataLayer.push({ "event":"myObject-is-available-notify-gtm-with-a-push" }); clearInterval(checkExist); } }, 100); })();

    Hey, it works, it sets an interval each 100 milliseconds and get our object is already available it clears the interval. We tested it, and it works, we're so proud of ourselves. But this time we didn't consider what will happen IF that object NEVER gets available... yep, you're right that code will be running forever, and depending on the code that it's ran inside it, it may kill the user's browser.

    If using loops in Variable you may need to take in mind that variables are being ran several times (not just once), so the problem is going to be even bigger.

    In this case we could have an incremental counter, so we could exit the interval execution, after 20 tries (20x100 = 2seconds).

     (function(){ var counter = 0; var checkExist = setInterval(function() { if(counter > 20) clearInterval(checkExist); if(typeof(window.myObject)!="undefined") { dataLayer.push({ "event":"myObject-is-available-notify-gtm-with-a-push" }); clearInterval(checkExist); } counter++; }, 100);})();

    So always think on a way for our loops to end in the case the condition is never met.