Integrating Google Tag Manager into a standard deployment process

Scaled Google Tag Manager development


When Google Tag Manager came out it promised to change the world, and in many ways it did.

It made what was once a very arduous task (getting marketing tracking tags live) very straightforward. All over the world marketers rejoiced at the ability to quickly add tracking to specific pages and actions on their websites and mobile apps.

The very aspect that made it attractive to agile digital marketers and an essential tool for all businesses was the very aspect that made those from a more technical background start to run for the hills.

This aspect was how easy it was to use and therefore how easy it was to deploy new tags to a website or an app. All of a sudden marketers, who used to rely on developers for everything, could now do this for themselves. What this meant however, was that standard development processes like code reviews, QA and controlled deployments were no longer the rule.

Consequently, this meant, especially for larger-scale organisations or ones with very separated development and marketing arms, was that there was no longer control over what code ended up in production. This led to two things;

  • Code bloat - which led to redundancies and slower page speeds

  • Incompatible scripts or flat out errors -  which led to bugs

How easily can issues occur?

In short, surprisingly easily.

At the very best of times, it was easy to disregard full regression testing on an entire code base (this is why automated testing is so important) and it was never done by the marketing department when marketing deadlines were approaching. Over time this manifests itself into a library of quick fixes and one-offs.  For example, I previously worked for a mining company and some back of the napkin sums that we did suggested that 15% of our production bugs were to do with incompatibilities between Google Tag Manager’ supplied scripts and the larger code base.

Steps to integrate

So, by this stage, it should be clear that Google Tag Manager deployments should be brought in from the cold and embraced as part of a wider deployment cycle. However the real trick is doing this without completely ruining the great part of using Google Tag Manager - its ease of use and speed to production.

So how do you do that? Below I have outlined some options of how it can occur.

Environment Specific Instances

There are two different options depending on your development practices, but either way, it is important to have separate instances running in your test environments and your production instance.

The main difference between the two options is the level of separation between your test environments and your production environment.

Environment Specific Containers

This option involves having two separate Google Tag Manager Containers in your account; one for Production and one for Test environments (development).

Multiple Environment Containers

Multiple Environment Containers

As the standard GTM script only varies on the id (“GTM-XXXXXXX”) this option is very easy to implement as a config setting for each environment.

The main benefit of this approach is that you can test tags and versions in your test environments (through your test container) very safe in the knowledge that nothing will ever appear in the live environment. Further to this, you can keep your production container very clean as only tags that are required in production will present in the live container.

Furthermore, it also has the added benefit of enabling a first simple troubleshooting step when issues do appear, i.e. “Which container is being used?”.

While some may say this is overkill and that separate workspaces/environments would suffice, the clear delineation between the two can be very helpful especially for teams where the analysts working in GTM and the development teams are not working together.

The main drawback to this option is the additional effort in terms of moving tags from your test container to your production container. So if you were going to go down this route I would recommend utilising the GTM API and doing this programmatically.

Container Specific Environments

The second option utilises the Google Tag Manager inbuilt Environments feature. In this option, you utilise versions within the same container to publish tag configurations to predefined environments. Versions can then be stepped up through environments and tested before going to live.

Environments in a Single Container

Environments in a Single Container

As with the previous option, this option can be implemented by simply altering the configs in your test environments to serve the GTM test environment’s snippet rather than the production snippet.

The main benefit of this option is that it provides an ease of deployment while also enforcing deployment processes. Further to this as you can publish different versions to different environments you have, in effect, complete control over your individual environments, which allows for them to be regression tested while also allowing for a more exact version history for use when troubleshooting.

The main drawback for this option is that it does little in the way of keeping the production container clean. This is because if different tags, triggers and variables are at different stages of the workflow (draft, in review, published, expired) in the one container it can quickly lead to analysts having an unclear picture of what is live and what is not.

Common Practices across both options

Hostname Lookup for different UAIDs

Hostname Lookup for different UAIDs

Additionally, to safeguard against incorrect configs, I find it useful to use lookup tables for constant strings, like Google Analytics IDs, based on the environment name, that point the tag to test buckets of the tracking systems (like Google Analytics) to further protect incorrect tag configurations from getting into production versions of trackers. This allows you to quickly roll out a backup configuration and also allows you to reduce the overall amount of tags and triggers required in your container. This is a win-win as far as I am concerned. Below I have outlined what this might look like for an Environment Google Analytics configuration.


Workspaces in Google Tag Manager are a great feature for busy accounts and can make your version history and change logs more robust and simpler to understand because at any time you can understand what people changed, where they made the changes and why they did it. This works in much the same way as how smaller commits and short-lived development branches can help speed up pull requests, i.e. having isolated workspaces can help simplify your containers.

If you are utilising environments, Workspaces are a vital part of your development strategy. In this instance, Workspaces should be used to house a set of tags that are going to become a version that will be tested much like a feature branch would be used.

However, by far the greatest feature of Workspaces is how they highlight and manage conflicts in configurations between Workspaces for you. This works whenever you try to sync your Workspace with the Default Workspace and GTM notices an issue.


Versions are a pretty big deal. While it is easy to shrug off version history and correct naming conventions they are critical in Google Tag Manager.

Google Tag Manager is effectively the Wild Wild West of development - anything goes and you can never be sure what’s happening in the next town over. Versions allow you to at least understand what has happened and what will happen.

The GTM Reference Guide goes through them in more detail but the main things to remember are;

  • Keep versions small and push them often

  • Keep them consistent (i.e. don’t put together a whole bunch of unrelated tags)

  • Stick to a naming convention that describes what the version achieves

Code Reviews & Approvals

At the end of the day, nobody's perfect and code reviews/approvals are a critical part of any deployment process.

If you’re at an organisation that is big enough to utilise the 360 Suite then the inbuilt approval process is a perfect way to input both a code review process and a stakeholder sign-off process into one. It inputs a workflow strategy into your deployment process and is really invaluable for larger teams and is one of the most underrated features of the entire 360 Suite.

However, for those of us who work with/for organisations who don’t really need 360 there are some other ways to insert code reviews into GTM.

The first step, no matter the approach, is to, before you start working, create a specific workspace and version for reviewing. Once this is done you have several options but I find it supremely useful to follow these principles;

  1. Raise a ticket for the work in your ticket tracking tool of choice (like JIRA) - there is no reason that GTM code should be handled any differently to your main code base

  2. Raise a Pull Request as per your normal flow and add a link to a preview of that version and define why you made the changed (and what you were trying to achieve)

  3. Peer reviewing/demoing - this helps greatly and also gets more people used to the GTM UI.

  4. Utilise the same definition of done that exists for the main code base

  5. Never publish GTM without fulfilling this definition of done - believe me people will ask for it to be done “just this once”

  6. Follow the standard deployment rules of your organisation - i.e. if you don’t deploy on Fridays from the main code base, don’t do it from GTM.

  7. If you are reviewing a pull request is raised be ruthless - no use phoning it in and assuming “GTM will be sweet”

Automated Testing

Automated testing is, thankfully, becoming more and more prevalent in the development world and utilising automated tests to streamline your Google Tag Manager instance should be no different.

When testing DataLayer objects it is firstly very important to have sufficient unit test coverage, just like any other code (I’m sensing a theme here).

However, this is just one piece of the puzzle and you should also include automated functional tests as part of any GTM version’s definition of done.

Luckily for us, there exists a multitude of open-source Repositories that handle this exact thing. Here are two that I recommend;

  1. Simo Ahava’s GitHub Repository for GTM utilises the framework Selenium and is great for anyone who already uses npm (you can read his guide about it here)

  2. Jan Exner’s GitHub Repository is great for teams who want to stay Tag Management Agnostic


The last step in the chain is actually deploying the tags to the production instance of GTM. This can be done either manually (through the GTM UI) or Programmatically (through the GTM API).


Manually is the easiest to start with and also meets the needs of the vast majority of use cases for Google Tag Manager. Deploying GTM manually simply involves hitting the big Publish button on a version or Workspace.

The benefits of this approach are ease of use and configuration.

The drawbacks to this approach depend greatly on your existing practices and how you configure your GTM containers and environments. However, they generally include:

  • Haphazard or conflicting deployment times

  • Lack of wider stakeholder knowledge of the deployment

  • Below standard testing

  • Manual recreation and merging of tags and variables

Programmatic (API)

Publishing through the GTM API is a great solution for those who want complete control over what goes where and when.

This is especially useful when the team is utilising two separate containers as they can automate the exporting and importing of a particular version of a container. It also makes it possible to deploy at the same time, under the same conditions as your main codebase.

The drawbacks to this approach are that it does take some setup time and can be overkill for organisations who aren’t publishing frequently. It also takes away some of the bigger benefits of GTM in terms of its standalone publishing ability.

Specific Triggers

Finally, it is very important that you have a GTM solution strategy that includes Trigger rules. Triggers in GTM determine when and where a tag should fire. Generally, you can fire things specifically or as general catchalls. It is best practice to be as specific as possible. If you only need to know what kind of product the user is adding to the cart when they actually add it to the cart then don’t fire the listener on DOM load, fire it on the exact event.

Further to this, I always find that the better your DataLayer implementation is the more you can generally afford to be more specific and secure with your triggers.

However, if you decide to be more general with your triggers you can get more tracking coverage for less effort, just be aware that if you do it too often - that way madness lies.

Most important point

If you only take one thing away from this article make it this:

Google Tag Manager’s ability to make tag deployment a simple and streamlined process is nothing short of amazing. That, however, doesn’t mean that us mere mortals can’t screw it up.