{"id":165183,"date":"2025-03-30T19:46:36","date_gmt":"2025-03-30T19:46:36","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/javascript-101-for-gtm-part-1\/"},"modified":"2025-03-30T19:46:36","modified_gmt":"2025-03-30T19:46:36","slug":"javascript-101-for-gtm-part-1","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=165183","title":{"rendered":"JavaScript 101 For GTM: Part 1"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p><em>Here\u2019s the link to <a href=\"https:\/\/www.simoahava.com\/analytics\/javascript-101-gtm-part-2\/\">part 2 of this JavaScript guide<\/a>.<\/em><\/p>\n<p>The thing about <a href=\"https:\/\/www.google.com\/tagmanager\">Google Tag Manager<\/a>, or any JavaScript tag manager for that matter, is that there\u2019s JavaScript involved. In fact, the tool itself is just a JavaScript library with some additional bells and whistles (such as a management UI). This means that to make the best of it, some knowledge of JavaScript is warranted, and that\u2019s the point of this post.<\/p>\n<p>This will not be a how-to or <a href=\"http:\/\/www.dummies.com\/how-to\/computers-software\/programming\/javascript.html\">JavaScript for dummies<\/a>, but rather a description of how JavaScript should be managed within GTM. However, I have added some of my favorite JavaScript learning resources to the mix, if you want to start from the beginning. JavaScript is a pretty easy programming language to learn, partly because it\u2019s been \u201cdumbed down\u201d and standardized so much over the years. The biggest difficulty with JavaScript, in my opinion, has nothing to do with the language itself. The biggest problem, by far, is how JavaScript is interpreted by the browsers out there. At its best, the same piece of code works perfectly across all browsers in existence. At its worst, you\u2019ll have to add complex cross-browser fallbacks to make sure your code runs even on certain modern browsers.<\/p>\n<p>The good thing about using GTM, or any library, is that the library itself usually takes care of cross-browser concerns for you. With GTM, however, this is limited to the tag and macro templates that you use. When you start adding custom JavaScript yourself, it\u2019s up to you to be wary of cross-browser support for your scripts.<\/p>\n<p><a href=\"http:\/\/www.quirksmode.org\/compatibility.html\">Quirksmode.org<\/a> is a pretty awesome resource if you want to find out more about browser compatibility.<\/p>\n<p>Without further ado, let\u2019s go the guide:<\/p>\n<ol>\n<li>\n<p>Favorite resources<\/p>\n<\/li>\n<li>\n<p>JavaScript in Google Tag Manager<\/p>\n<\/li>\n<li>\n<p>The dataLayer structure<\/p>\n<\/li>\n<li>\n<p>Interacting with dataLayer<\/p>\n<\/li>\n<li>\n<p>Custom HTML tag<\/p>\n<\/li>\n<li>\n<p>Custom JavaScript macro<\/p>\n<\/li>\n<\/ol>\n<p>This is, again, just the first of a two-part series. I\u2019m sorry, I\u2019m just lazy. The sun is finally shining here, I\u2019m looking at the garden, and for some reason the notion of outdoors, smell of freshly cut grass and the sweet liberation only a can of cold beer can provide are edging their way to the top of the \u201cthings I\u2019d rather be doing than blogging\u201d list, which is a very, VERY short list indeed.<\/p>\n<p>                <span class=\"simmer\"><br \/>\n  <span class=\"close\">X<\/span><\/p>\n<p>\n    <span class=\"fa fa-md fa-bell\"\/><br \/>\n    <strong>The Simmer Newsletter<\/strong>\n  <\/p>\n<p>\n    Subscribe to the <a href=\"https:\/\/www.simoahava.com\/newsletter\/\">Simmer newsletter<\/a> to get the latest news and content from Simo Ahava into your email inbox!\n  <\/p>\n<p>  <\/span><\/p>\n<h2 id=\"1-favorite-resources\">1. Favorite resources<\/h2>\n<p>Here are some resources to get you going on your JavaScript learning trail:<\/p>\n<p><strong>WEBSITES<\/strong>:<\/p>\n<p><a href=\"http:\/\/www.codecademy.com\">Codecademy<\/a> &#8211; Interactive learning portal for a number of different programming disciplines. Their JavaScript track is excellent to get you started with the language.<\/p>\n<p><a href=\"https:\/\/www.codeschool.com\/paths\/javascript\">Code School<\/a> &#8211; Another training portal. Their JavaScript track is good as well.<\/p>\n<p><a href=\"http:\/\/www.w3schools.com\/js\/DEFAULT.asp\">w3schools.com<\/a> &#8211; Better as a reference than as a learning resource, but lots of good content nonetheless.<\/p>\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\">MDN Web API Interfaces<\/a> &#8211; Reference tool for all the web APIs you\u2019ll ever need.<\/p>\n<p><strong>BOOKS<\/strong>:<\/p>\n<p><a href=\"https:\/\/www.amazon.com\/JavaScript-Good-Parts-Douglas-Crockford\/dp\/0596517742\">Douglas Crockford &#8211; JavaScript: The Good Parts<\/a> &#8211; One of the best books on JavaScript best practices out there (intermediate to advanced).<\/p>\n<p><a href=\"https:\/\/www.amazon.com\/Professional-JavaScript-Developers-Nicholas-Zakas\/dp\/1118026691\">Nicholas Jakas &#8211; Professional JavaScript for Web Developers<\/a> &#8211; My favorite JavaScript book. The most complete guide out there.<\/p>\n<p><a href=\"http:\/\/eloquentjavascript.net\/\">Marijn Haverbeke &#8211; Eloquent JavaScript<\/a> &#8211; Excellent book on JavaScript, with a free digital edition!<\/p>\n<p><strong>BLOGS<\/strong>:<\/p>\n<p><a href=\"http:\/\/www.dailyjs.com\">DailyJS<\/a> &#8211; Daily tips on JavaScript.<\/p>\n<p><a href=\"http:\/\/davidwalsh.name\/\">David Walsh Blog<\/a> &#8211; Lots of stuff on web development, with many in-depth articles on JavaScript.<\/p>\n<p><a href=\"http:\/\/joejimzs.com\/\">Joe Zim\u2019s JavaScript Blog<\/a> &#8211; Actionable tips and guides for JavaScript and related frameworks.<\/p>\n<p>These are my favorite resources. If you have more suggestions, let me know via e-mail or in the blog comments.<\/p>\n<h2 id=\"2-javascript-in-google-tag-manager\">2. JavaScript in Google Tag Manager<\/h2>\n<p>In almost all of my <a href=\"https:\/\/www.simoahava.com\/tags\/google-tag-manager\/\">Google Tag Manager posts<\/a>, I use JavaScript in one way or another to get the task done. That\u2019s because JavaScript is THE language of Google Tag Manager. The library itself is a JavaScript library, and all the bells and whistles of the UI are meant to control the type of JavaScript that the tool injects on the web page.<\/p>\n<p>However, you can\u2019t just go around shooting JS code wherever you like. In the GTM UI, JavaScript can only be added <strong>in the context of a script<\/strong>. Currently, there are two places which accept JavaScript code raw and unfiltered: the <strong>Custom HTML Tag<\/strong> and the <strong>Custom JavaScript Macro<\/strong>. So don\u2019t try to write JavaScript in other tag fields, it won\u2019t work.<\/p>\n<div style=\"aspect-ratio: 1448 \/ 569;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/06\/script-context.jpg\" title=\"script-context\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"569\" width=\"1448\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/06\/script-context.jpg#ZgotmplZ\" alt=\"script-context\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>So if you want to perform custom JavaScript functions, you will either need to create a Custom HTML Tag which executes some code, or if you want to use JavaScript to access DOM elements, for example, you might want to create a Custom JavaScript macro. We\u2019ll get to these soon, don\u2019t worry.<\/p>\n<p><strong>FURTHER READING<\/strong>:<\/p>\n<h2 id=\"3-the-datalayer-structure\">3. The dataLayer structure<\/h2>\n<p>A JavaScript tag management solution is based on <em>code injection<\/em>. This means that the code it executes on your site is alien to the page template. The only thing the page template originally has is <a href=\"https:\/\/www.simoahava.com\/analytics\/container-snippet-gtm-secrets-revealed\/\">the container snippet<\/a>. This snippet acts as the invitation for GTM to perform its magic on your page.<\/p>\n<p>Because GTM injects the code it wants to execute, it\u2019s vital that it uses its own data structure. If there was no proprietary data model, all the variables GTM would be accessing \/ modifying would run the risk of causing conflicts with other libraries. For instance, say you have a global variable <code>pageHeader<\/code> created by your developers, and it stores the main header of your page template. Then GTM comes along and uses <code>pageHeader<\/code> to manipulate the document title that is pushed to Google Analytics. Because it accesses the same global variable that you use to store on-page information, the risk that GTM would break your page template becomes a horrible reality.<\/p>\n<p>With dataLayer, successful (read: smart) use of GTM is restricted to only those variables that are exposed within the dataLayer structure. Thus the only risk you run is having another library which ALSO uses dataLayer (spelled exactly like that). The better known that the dataLayer standard becomes, the less of a risk this will be, since other libraries will know to avoid using this name.<\/p>\n<p>dataLayer is a <strong>JavaScript object<\/strong> of the type <strong>Array<\/strong>. An Array is a special type of object. The difference is that in JavaScript, objects have <em>properties<\/em>, whereas Arrays have <em>members<\/em>. An Array member can be an object.<\/p>\n<p>Object properties are defined with specific notation, e.g.:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> sampleObject = {<span style=\"color:#a50\">'First-name'<\/span>: <span style=\"color:#a50\">'Simo'<\/span>};\nalert(sampleObject[<span style=\"color:#a50\">'First-name'<\/span>]);\nalert(sampleObject.First-name); <span style=\"color:#aaa;font-style:italic\">\/\/ Error!\n<\/span><\/code><\/pre>\n<\/div>\n<p>So this is an object, not an Array. If you want to get the terminology straight, in the first line I created an object using <strong>object literal notation<\/strong>. That\u2019s the curly bracket thingamajig there. In the second line, I retrieved the \u2018First-name\u2019 property of the object by using <strong>square bracket notation<\/strong>. You could also use <strong>dot notation<\/strong> to access object properties (third line), but with \u2018First-name\u2019 that would cause a <strong>NaN<\/strong> (Not a Number) error, because the hyphen in the name is interpreted as a minus sign. Thus JavaScript in its infinite wisdom is misguided enough to think that <strong>sampleObject.First<\/strong> returns a number of which another number <strong>name<\/strong> is subtracted. But never mind, this was just a detour.<\/p>\n<p>The thing to understand about dataLayer is that an Array behaves a bit differently than your run-of-the-mill JavaScript object. First of all, an Array is like a table or queue, however you want to look at it. You can add multiple members to it, and any one of these members can be of any JavaScript type, such as objects.<\/p>\n<p>In GTM, dataLayer is (almost) always interpreted as an Array of objects. Thus you can have the sampleObject I created above as a member of dataLayer:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> dataLayer = [{<span style=\"color:#a50\">'First-name'<\/span>: <span style=\"color:#a50\">'Simo'<\/span>}];\n<\/code><\/pre>\n<\/div>\n<p>As you can see, it doesn\u2019t matter any more that the object was called \u2018sampleObject\u2019, since from this moment on it will only be referenced to using its index number in the Array. Index numbers start from 0, so if this is the first object in the array, it\u2019s reference is <strong>dataLayer[0]<\/strong>. The next object that is added to the Array would have index number 1, and so on.<\/p>\n<p>You can access object properties in an Array using the same notation as you just learned of in the beginning of this chapter. However, first you need to know which index the object whose property you want to access resides in.<\/p>\n<p>So, if you\u2019re still following me, to access the \u2018First-name\u2019 property of the FIRST dataLayer index, you\u2019d need to use something like this:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\">alert(dataLayer[<span style=\"color:#099\">0<\/span>][<span style=\"color:#a50\">'First-name'<\/span>]);\n<\/code><\/pre>\n<\/div>\n<p>This would pop up a dialog with \u201cSimo\u201d. However, in GTM you don\u2019t need to worry about dataLayer index numbers, since you can just use the <a href=\"https:\/\/www.simoahava.com\/analytics\/macro-guide-google-tag-manager\/\">Data Layer Variable Macro<\/a>. I\u2019ll have more about interacting with dataLayer in the next chapter.<\/p>\n<p><strong>FURTHER READING<\/strong>:<\/p>\n<h2 id=\"4-interacting-with-datalayer\">4. Interacting with dataLayer<\/h2>\n<p>In GTM, you basically interact with dataLayer in three different ways:<\/p>\n<ol>\n<li>\n<p>First, you <strong>define<\/strong> dataLayer as an Array<\/p>\n<\/li>\n<li>\n<p>Next, you <strong>push<\/strong> objects and properties into dataLayer<\/p>\n<\/li>\n<li>\n<p>Finally, you access these properties using a Data Layer Variable <strong>Macro<\/strong><\/p>\n<\/li>\n<\/ol>\n<p>Let\u2019s go through these step-by-step.<\/p>\n<p>You define dataLayer by declaring the variable and setting its type to Array. The most common way to do this is to use literal notation:<\/p>\n<p>This tells your page that a new variable called dataLayer has now been declared, and the square brackets define its type as Array. After this, you can start pushing stuff into the structure, or if you have some properties that you already want to push, you can just add them to the declaration:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> dataLayer = [{\n    <span style=\"color:#a50\">'pageTitle'<\/span>: <span style=\"color:#a50\">'Homepage'<\/span>,\n    <span style=\"color:#a50\">'visitorType'<\/span>: <span style=\"color:#a50\">'Loyal customer'<\/span>,\n    <span style=\"color:#a50\">'loggedIn'<\/span>: <span style=\"color:#00a\">true<\/span>\n}];\n<\/code><\/pre>\n<\/div>\n<p>So here I create dataLayer as an Array (that\u2019s the square brackets) with a single object (that\u2019s the curly brackets) with three properties (that\u2019s the \u2018key\u2019: \u2018value\u2019,) stuff. As you can see, there\u2019s no comma after the last property. Also, <strong>true<\/strong> does not have single quotes around it, since I\u2019m storing a value of Boolean type (true\/false) and not a string.<\/p>\n<p>The thing about the dataLayer declaration is that <strong>it should only ever be done once<\/strong>. You see, every time you redeclare a variable, its previous reference is overwritten! You have to be really careful about this, since if your developers accidentally add the dataLayer declaration twice on your page, its previous properties will be overwritten by the second declaration. That\u2019s why its safest to declare the structure once and then just consistently use <strong>push()<\/strong> for all modifications later.<\/p>\n<p>The <strong>push()<\/strong>-method is what all Arrays come equipped with. Using this method adds an object to the end of the Array, creating a new index for it automatically. Thus nothing is overwritten. You can have a dozen objects with exactly the same properties in dataLayer, and you\u2019d get no errors. Note that GTM\u2019s Data Layer Variable Macro has a way of navigating around this issue (see below).<\/p>\n<p>To push a new object into dataLayer, the following notation should be used:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\">dataLayer.push({<span style=\"color:#a50\">'loggedIn'<\/span>: <span style=\"color:#00a\">false<\/span>});\n<\/code><\/pre>\n<\/div>\n<p>This just pushed a new object into dataLayer with a single property: \u2018loggedIn\u2019 with the value false. So I can easily have dataLayer with two objects, both with property \u2018loggedIn\u2019 being something different. That doesn\u2019t matter, since they\u2019re in separate objects.<\/p>\n<div style=\"aspect-ratio: 419 \/ 147;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/06\/datalayer.jpg\" title=\"datalayer\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"147\" width=\"419\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/06\/datalayer.jpg#ZgotmplZ\" alt=\"datalayer\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Trying to push the same property twice into the SAME object would not result in an error, either. However, only the last property would remain in the object.<\/p>\n<p>The thing about <strong>push()<\/strong> is that it won\u2019t work if dataLayer hasn\u2019t been declared as an Array. That\u2019s why in your page template the following is a good way of prefixing the dataLayer.push() call:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#0aa\">window<\/span>.dataLayer = <span style=\"color:#0aa\">window<\/span>.dataLayer || [];\ndataLayer.push(...);\n<\/code><\/pre>\n<\/div>\n<p>The first line checks if dataLayer has already been declared. If it has, all is well, but if it hasn\u2019t, it is then and there declared as an Array. This basically makes it so that the push() method will almost always work. The only way it won\u2019t work is if dataLayer HAS been declared but as something other than an Array (pretty rare situation).<\/p>\n<p>Note that when working in GTM (Custom HTML and Custom JavaScript), you won\u2019t have to add this check to your code, since the GTM container snippet will always declare dataLayer for you if you haven\u2019t done so explicitly in the page template.<\/p>\n<p>Finally, the way that the Data Layer Variable Macro works is that when you give it a property whose value it must return, it starts going through the dataLayer properties one by one, starting from the newest. If it finds a property with the name you gave, it returns its value and stops traversing dataLayer. So if you have two objects in dataLayer with the property \u2018loggedIn\u2019, only <strong>the most recent property value<\/strong> will be returned by the Data Layer Variable Macro.<\/p>\n<p>In layman\u2019s terms, this means that for Google Tag Manager, pushing an object into dataLayer with a property that already exists in dataLayer <strong>overwrites the previous property value with the new one<\/strong>. Of course, it doesn\u2019t really overwrite anything, but the Macro is only interested in the latest value.<\/p>\n<p>There is a quirky exception to this, and that is if you push an Array into dataLayer.<\/p>\n<p>If you then push another Array with the same name, GTM will only \u2018overwrite\u2019 those Array indices that are shared by the two Arrays, but if the first Array had more indices, then those will remain for GTM to use. Allow me to demonstrate:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\">dataLayer.push({<span style=\"color:#a50\">'products'<\/span>: [<span style=\"color:#a50\">'a'<\/span>, <span style=\"color:#a50\">'b'<\/span>, <span style=\"color:#a50\">'c'<\/span>, <span style=\"color:#a50\">'d'<\/span>]});\n...\ndataLayer.push({<span style=\"color:#a50\">'products'<\/span>: [<span style=\"color:#a50\">'e'<\/span>, <span style=\"color:#a50\">'f'<\/span>]});\n<\/code><\/pre>\n<\/div>\n<p>In the first line, I push an Array with four members (a, b, c, d). A bit later on, I push another Array with the same name, but this time with just two members. If GTM would be consistent, the second time around the Data Layer Variable Macro would have just two members in the \u2018products\u2019 Array, but right now GTM works so that it just overwrites the first two indices in the Array. Thus the Macro would actually see \u2018products\u2019: [\u2018e\u2019, \u2018f\u2019, \u2018c\u2019, \u2019d\u2019]. This is a bit buggy to me, as to be consistent the second Array push should make it so that the Macro only accesses the values in the second Array.<\/p>\n<p>Phew, this was a lot of information, I hope you\u2019re still with me here.<\/p>\n<h2 id=\"5-custom-html-tag\">5. Custom HTML Tag<\/h2>\n<p>A Custom HTML Tag allows you to inject HTML markup in the site. This means that if you want to run custom JavaScript in a Custom HTML Tag, you need to create the script context for the code. In HTML, you establish a script context with the <code><script\/><\/code> element:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-html\" data-lang=\"html\">div <span style=\"color:#1e90ff\">id<\/span>=<span style=\"color:#a50\">\"html_markup_here\"<\/span>&gt;This is still just normal HTML markup<span style=\"color:#1e90ff;font-weight:bold\">div<\/span>&gt;\nscript&gt;\n  alert(<span style=\"color:#a50\">\"And this is JavaScript!\"<\/span>);\n<span style=\"color:#1e90ff;font-weight:bold\">script<\/span>&gt;<\/code><\/pre>\n<\/div>\n<p>If you try to run JavaScript without the script block, you\u2019ll run into some serious validation errors.<\/p>\n<p>Note that you don\u2019t need the legacy <strong>type=&#8221;text\/javascript\u201d<\/strong> attribute in your <code><script\/><\/code> tags, unless you\u2019re still using HTML4 (<em>gasp<\/em>) and you want your code to validate. All modern browsers can do the math and make the logical conclusion that a SCRIPT element with JavaScript code inside should be interpreted as, surprise surprise, JavaScript.<\/p>\n<h2 id=\"6-custom-javascript-macro\">6. Custom JavaScript Macro<\/h2>\n<p>In Google Tag Manager, a macro is designed to return a value when it is called. That\u2019s why you have all those cool out-of-the-box macros out there, which each return some amazing piece of information about the site, the page, or the visitor.<\/p>\n<p>If you haven\u2019t already, be sure to read <a href=\"https:\/\/www.simoahava.com\/analytics\/macro-guide-google-tag-manager\/\">my macro guide<\/a>, as it sheds more light on this topic.<\/p>\n<p>With a Custom JavaScript Macro, it\u2019s function (pun intended) is also to return a value. If there\u2019s no return statement or if the macro isn\u2019t wrapped in a function (only functions can return values), you\u2019ll run into errors in GTM.<\/p>\n<p>So here are the things to remember:<\/p>\n<p><strong>1. Always wrap your Custom JavaScript macro in an anonymous function.<\/strong><br \/><strong>2. Always return a value (any value) with a Custom JavaScript macro<\/strong><\/p>\n<p>An anonymous function is a function without a name. Why is this necessary? Well, you don\u2019t create a function in a macro so that you call it on a whim using its name. No, the sole reason for a JS macro\u2019s existence is that it\u2019s called and its value is resolved at the same time, using the {{macro}} syntax of GTM. This is, again, one of the ways GTM ensures that global variables are not being messed about with. If you could name your functions, you might be using a name reserved for some other library. This would potentially have nightmarish results.<\/p>\n<p>And why return a value? Well, to reiterate, a macro\u2019s function is <em>to return a value<\/em>. When you call a JS macro, it resolves some operation right then and there with all the data available at the moment it was called. It then returns a value based on this operation. What would be the function of using the macro syntax {{macro}} in your fields if not to retrieve a value? Stop asking silly questions.<\/p>\n<p>An example of a proper Custom JavaScript macro:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">return<\/span> <span style=\"color:#0aa\">window<\/span>.location.href.toLowerCase();\n}\n<\/code><\/pre>\n<\/div>\n<p>Here you have an anonymous function declared on the first line, a return statement with the operation on the second line, and the closing of the function block on the third line.<\/p>\n<p>When this macro is called, it returns the URL of the current page transformed into lower case. This is a prototypical GTM Custom JavaScript Macro. It\u2019s just an anonymous function which does not accept parameters. Thus its sole objective is to return a value, based on some operation on some other value that can be found in the document object model (more on this later). Remember that you can access other macros in your Custom JavaScript Macros, so you can do a lot of pretty complex stuff with Custom JavaScript macros. For example, the following macro returns the first folder in the URL path (e.g. \u201csimo\u201d in \/simo\/articles\/analytics):<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">return<\/span> {{url path}}.split(<span style=\"color:#a50\">\"\/\"<\/span>)[<span style=\"color:#099\">1<\/span>];\n}\n<\/code><\/pre>\n<\/div>\n<p>A Custom JavaScript Macro is probably the most versatile tool you have available in your GTM toolbox, and you should definitely check out my other <a href=\"https:\/\/www.simoahava.com\/tags\/google-tag-manager\/\">Google Tag Manager posts<\/a> for creative ways to use them.<\/p>\n<h2 id=\"conclusions\">Conclusions<\/h2>\n<p>Phew, that was a lot information there. I\u2019m going to have to split this into a two-parter, just to keep me motivated \ud83d\ude42<\/p>\n<p>I hope you take a look at the JavaScript resources I wrote of in the first chapter. Even if you\u2019re well versed in the craft of client-side programming, most of the time its good to refresh your knowledge with some \u201cbasic stuff\u201d.<\/p>\n<p>The thing with GTM is that in addition to functioning like your average JavaScript library, it comes along with certain proprietary features that require you to adapt your JavaScript skills somewhat. The purpose of this (and the following article) are just that: make you knowledgeable of what GTM requires from you and the code you create.<\/p>\n<p><em>Here\u2019s the link to <a href=\"https:\/\/www.simoahava.com\/analytics\/javascript-101-gtm-part-2\/\">part 2 of this JavaScript guide<\/a>.<\/em><\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Here\u2019s the link to part 2 of this JavaScript guide. The thing about Google Tag Manager, or any JavaScript tag manager for that matter, is that there\u2019s JavaScript involved. In fact, the tool itself is just a JavaScript library with some additional bells and whistles (such as a management UI). This means that to make [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":165184,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[32680,29091,3341],"dealstore":[],"offerexpiration":[],"class_list":["post-165183","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-gtm","tag-javascript","tag-part"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>JavaScript 101 For GTM: Part 1 - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=165183\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JavaScript 101 For GTM: Part 1 - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"Here\u2019s the link to part 2 of this JavaScript guide. The thing about Google Tag Manager, or any JavaScript tag manager for that matter, is that there\u2019s JavaScript involved. In fact, the tool itself is just a JavaScript library with some additional bells and whistles (such as a management UI). This means that to make [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=165183\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-03-30T19:46:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1448\" \/>\n\t<meta property=\"og:image:height\" content=\"569\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=165183#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=165183\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"JavaScript 101 For GTM: Part 1\",\"datePublished\":\"2025-03-30T19:46:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=165183\"},\"wordCount\":3135,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=165183#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg\",\"keywords\":[\"GTM\",\"JavaScript\",\"PART\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=165183#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=165183\",\"url\":\"https:\/\/fivemor.com\/?p=165183\",\"name\":\"JavaScript 101 For GTM: Part 1 - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=165183#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=165183#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg\",\"datePublished\":\"2025-03-30T19:46:36+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=165183#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=165183\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=165183#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg\",\"width\":1448,\"height\":569},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=165183#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JavaScript 101 For GTM: Part 1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"JavaScript 101 For GTM: Part 1 - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=165183","og_locale":"en_US","og_type":"article","og_title":"JavaScript 101 For GTM: Part 1 - Som2ny Network","og_description":"Here\u2019s the link to part 2 of this JavaScript guide. The thing about Google Tag Manager, or any JavaScript tag manager for that matter, is that there\u2019s JavaScript involved. In fact, the tool itself is just a JavaScript library with some additional bells and whistles (such as a management UI). This means that to make [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=165183","og_site_name":"Som2ny Network","article_published_time":"2025-03-30T19:46:36+00:00","og_image":[{"width":1448,"height":569,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=165183#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=165183"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"JavaScript 101 For GTM: Part 1","datePublished":"2025-03-30T19:46:36+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=165183"},"wordCount":3135,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=165183#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg","keywords":["GTM","JavaScript","PART"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=165183#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=165183","url":"https:\/\/fivemor.com\/?p=165183","name":"JavaScript 101 For GTM: Part 1 - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=165183#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=165183#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg","datePublished":"2025-03-30T19:46:36+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=165183#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=165183"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=165183#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/script-context.jpg","width":1448,"height":569},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=165183#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"JavaScript 101 For GTM: Part 1"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/165183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=165183"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/165183\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/165184"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=165183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=165183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=165183"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=165183"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=165183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}