Getting rid of the inflexible side of Google Tag Manager

Google Tag Manager has been a nice tool, but often a bit inflexible. With the new feature “Custom JavaScript for Macros”, that has changed. In this sample case, I’ll show you how this new feature helps you reduce redundancies and shrink your clutter from 2 tags, 2 macros, and 2 rules, to just 1 tag and 1 macro.

Google Tag Manager (GTM) may still be behind many of the paid enterprise tag management systems (TMS), but it is getting better and better. Recently, Google released a little feature with a lot of power – it is called “Custom JavaScript” for Macros. No, I do not mean the old “Custom HTML” tag that allows you to execute JavaScript tags. That one is mainly there to integrate the many tools for which GTM doesn’t offer a turnkey integration (clicking your tag together instead of coding it). “Custom JavaScript for Macros” instead is a feature that allows you to make your Macros and rules very flexible and reduce redundancies.

Example case: One GA Code, several domains and subdomains

In our case (here a simplified version of it) – a very common case I might add – the client used Google Analytics and wanted to track visitors across all of his many subdomains. For this to work, you need to set the domain in your tracking code to the name of the main domain. In Google Tag Manager, you can do this by entering the client’s main domain into the field “Domain Name” when setting up a Google Analytics tag.

Google Tag Manager set domain in tracking code

Now, this client also had one or several “test” platforms in addition to the “live” platform.  But the test and staging platforms ran under different domains (not just different subdomains), for example:

  • etc.

Google Analytics was to run on the testing platforms as well. But if you set the domain name in the GA tracking code to “”, yet the actual domain name is “”, the code will not be executed because GA’s first-party cookie can’t be set by a third-party domain.

Until recently: 2 tags, 2 macros, 2 rules

So until recently, the recommended way to work around this was creating extra work for your developers by inserting the current main domain into the GA data layer (in the HTML code on the page) and then insert this data layer variable’s value into the “Domain” field in your GA tag. A very inflexible solution and exactly the thing you wanted to avoid now that you have a Tag Management System. So if you wanted to do it without your IT, you had to create a lot of redundant clutter:

  • Two GA tags:
    • A: One tag with the domain name set to the main live domain (
    • B: One tag with the domain name set to the main testing domain (
  • Two “Constant String” Macros (recommended because if the testing domain changes one day, you don’t have to change all the tags where you’ve hard-coded the old domain name)
    • Main live domain
    • Main testing domain
  • Two rules:
    • When on hostname that belongs to the live platforms (rule for firing tag A)
    • When on hostname that belongs to the testing platforms (rule for firing tag B)

Now this is a simplified example. The client actually had yet another testing domain, and he needed other tags to run on both environments. Some of them had the same problem, so for these tags, we would have had this kind of tag proliferation too.

Now: One tag, one rule, one macro

What we would have loved to have had was a more dynamic form of a macro. One that doesn’t just return the current hostname, a data layer variable or a constant string, but one that would return the appropriate domain name to be set in the Google Analytics tag.

Now, with Custom JavaScript for Macros, we get exactly what we want. It allows you to put it all into one macro, no rule, and one tag. 

One Macro of the type “Custom JavaScript”: I called it “Return domain name to be set”.
Google Tag Manager Custom Javascript

Within a Custom JavaScript Macro, you define an anonymous function that returns a value. The return value becomes the value of the Macro.

In our example, our function checks the current hostname (the “domain”). If the hostname looks like we are on a testing platform, the return value becomes “” (the main testing domain). If not, we return the main live domain. 

Google Tag Manager More Java Script


(Remember that there can be subdomains, so we cannot just set the Macro to the current hostname.)

  • One Tag: Instead of two GA Tags, I need only one. In the field “Domain”, I refer to the Macro “Return domain name to be set” that I have just created. My tag will now set the domain to the value that my Macro returned, “” or “”: 

    Google Tag Manager Domain Name

  • No rule: The only use for the two old rules was to fire tag A or tag B depending on whether I was on the live or test domain. But since my dynamic macro now automatically alters the tag to fit both scenarios, I can discard these rules. I can now simply fire my tag on any page. So I just use the preconfigured “All pages” rule – that’s it.

You could apply the same logic if you want to fill another field in your tag based on more dynamic rules. For example, you could use it to route your traffic into a different GA property ID depending on whether you are on your test or live system without having to set up 2 tags for that. 

Rules with dynamic instead of hard-coded patterns

But Custom JavaScript Macros can also be used to “dynamicize” tag rules: for example, you want to fire tags depending on whether there is a certain pattern in the URL (e.g., a Regular Expression to identify your Conversion page). Since many tags and rules need this pattern, without Custom JavaScript Macros you would need to hard-code the pattern into each of the rules:

Google Tag Manager Hard Coding

Note that you can’t compare a macro-based value like {{url}} with another macro-based value. So this would not work:

Google Tag Manager more hard coding

But with Custom JavaScript Macros, you can simply do it like this:

Google Tag Manager Another Javascript Macro

Instead of having the rule test the URL itself for the pattern, I let the rule test the return value of my Custom JavaScript Macro “Crazy Pattern URL Test Macro”. This Macro returns “true” if the pattern is found in the URL.

If the pattern changes, I just change this one Macro – no need to edit all those rules, then forget one or mistype one and then spend hours finding your mistake.

I hope you can understand why the Custom JavaScript Macros are my favorite feature in Google Tag Manager: They save time, erase redundancies, and de-clutter my tag, rule and macro library.

One drawback: Yet more JavaScript

The one drawback of course is that you need some basic JavaScript know-how. But as with any Tag Management System, it is impossible to get the bigger benefits without JavaScript if you want to run more than a couple of simple tags.

Share your experiences

Have you used Custom JavaScript Macros as well? Please do share your case in the comments.


  1. says

    Hi Lukas,
    I have been reading a couple of your articles and think that you present great resources to maximize data resources from GA. As such, I was wondering if you could answer this question:

    Whats the best way to customize GA tracking when you want to track several domains? Which would translate into wanting to understand traffic attribution, conversion contribution, etc. I ask, because I see a lot of companies that have a parent site (Their main brand or website) and then use Microsites or landing pages focused on products or services.

    Thanks and keep up the great content!

    Best Regards,


  2. says

    Hi Christian,

    thank you very much for the kind comment.

    Your question about multi-domain tracking has very many aspects and viewpoints. To answer this satisfactorily I would have to invest quite some time, so I am sorry I have to pass on that right now since the holiday season is keeping everyone here quite busy. But I will try to get back to that later. Sorry about that!

    Thanks again and have a great day!

  3. Stuart says

    I was recently looking for a way to use GTM across several sites we own that have the same structure just different branding. To ease maintenance and make the most of reusing listeners and events across the sites we chose to use the same container and just fire GA with domain rules.

    However, to overcome the need for multiple GA tags for the same event on the different sites I came across your solution, then I discovered the Lookup Table in GTM that would likely satisfy your code above and my need for different tracking ID’s based on domain.

  4. says

    Hi Stuart,

    great addition, thanks! Yes, Lookup Tables came out some months after this article, nowadays, for easy categorizations like the one I describe in this article, these are now a more non-techie-friendly way of doing this. :)

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>