GTM testing with Charles

GTM Preview Mode not working? Need an alternative method for validating changes made in GTM? 

Making changes to analytics configurations and setups is a common use case for digital marketers. In this blog, we’ll discuss some methods and best practice for making changes using Google Tag Manager with some features within Charles – a great tool to monitor traffic that we use to support our clients.


Whenever changes are made in a GTM container, these must be tested before being deployed to production. To facilitate validation, GTM supports a ‘preview mode’, where users can locally try out container updates to confirm these work as expected. Preview Mode works locally, meaning changes are only visible to the user invoking Preview Mode.

In 99% of cases, making changes and validating in GTM Preview Mode is a perfectly viable workflow. However, for some clients we’ve found ourselves working with some unique testing requirements, hitting the limit of GTM’s native Preview Mode. In these cases, we’ve had to resort to some novel approaches for checking changes we make in GTM.

Scenario 1 – Client A

Recently, we identified a reference to an undefined variable in the client’s GTM tag. When the tag ran on their live site, it would fail with a standard JavaScript error. Curiously, if we enabled GTM’s Preview Mode and observed the behaviour of the tag in question, the problem did not occur. In other words, in production the tag failed. In Preview Mode (all other factors equal), the tag did not fail, as though running Preview Mode somehow corrected the underlying problem (we never were able to figure out why this was the case – it could be that GTM Preview Mode works internally by globally defining references to certain variables, and it so happened our problem reference therefore actually pointed to something that was defined – so long as Preview Mode was active). This behaviour makes it clear Preview Mode is unsuitable for testing any fixes addressing the original problem (reference to an undefined variable).

We needed a testing method that would somehow allow us to validate any fixes without relying on Preview Mode.

Scenario 2 – Client B

Lynchpin have been assisting another client in the deployment of certain scripts in GTM. These support acquisition tracking for mobile app downloads. The detail isn’t necessarily important, but the scripts work by changing the links behind download CTAs if the user is using a mobile browser to view the client group website. If a user is on desktop, the CTA download links remain unchanged.

To end-end test our deployment, we therefore needed a way to invoke GTM Preview Mode on a mobile device as well as on desktop (i.e., given some behaviours of the script-under-test are observable only on mobile, and some only observable on desktop). At the time GTM Preview Mode did not support this sort of linkage to other devices (i.e., mobiles), presenting a challenge for validation.

Again, we needed a testing method that bypassed GTM Preview Mode that still preserved the safety and integrity of the client group’s live sites (we don’t want to just push live and test in prod!).

Novel testing

To address the issues described above we opted for a solution that leveraged one of Charles’ lesser used features: the ‘Map Remote’. Map Remotes allow us ask Charles to download something different to what was originally requested over the network, depending on some conditions. For instance, you may configure a map remote to point requests for www.google.com to www.lynchpin.com. When the browser issues a network request for the former domain – a request which goes through Charles – the tool will instead route that request to the latter domain. As a result, you’d see the Lynchpin website in the browser, but the address bar would read www.google.com (this specific example can be is handy when needing to validate cookie behaviour in the context of domain changes).

Map Remotes are not limited to the site requested via the address bar; any network request piped through Charles may be re-rerouted. This means we can ‘inject’ a different GTM container (or any resource for that matter!) to the one used on a given website (in a totally isolated manner – since Charles and its Map Remote are only running on your machine, your changes are not observable outwith that context). This feature, combined with our ability to route mobile traffic from a phone through Charles, means we can solve our GTM testing problems for each of the scenarios above.

Testing the solution to Scenario 2

We first piped network traffic from our test device through Charles in the usual manner (ensuring SSL proxying was correctly configured). We then created a brand new (blank) GTM container, into which we imported our changes from Client B’s production container (we’d already implemented the new Tags and Triggers we required). At this stage, we have a brand new container that holds the changeset we want to validate on the live group site. We also know for sure that container is unused on the public internet (given we own it, and just created it).

Once our ‘test container’ is configured, we can publish its changes live (again, a safe operation given nothing on the internet actually points to that container). Finally, we configure a Charles Map Remote such that when loading the client’s websites, our test container (with our changes) loads instead of the one originally deployed. Given our mobile device piped network traffic through Charles, we were able to safely test our changes in the required mobile context.

Testing the solution to Scenario 1

Again, we defined a new GTM container, imported our changes, and injected that container into Client A’s live sites using a Map Remote. We needed to eliminate GTM Preview Mode from the testing method for this scenario, and Map Remotes allowed us to do just that. This was the reason for using Map Remotes here, as opposed to the need to test changes on mobile as with Client B.

Alternative methods

It is possible to access GTM within a mobile device in the first place. Users might then be able to trigger Preview Mode from there and test this way. However, GTM is not designed for use on a mobile and in our experience, attempting to utilise Preview Mode in this manner proved extremely flaky.

You may also consider an alternative container structure where each pre-production site points to individual, pre-production GTM containers. This is a workflow more closely resembling Adobe’s ‘Tags’ tool (formerly client side ‘Platform Launch’). This testing method means that each test site is powered by an individual, isolated set of changes. However, unlike Adobe’s ‘Tags’ whose testing tools are exposed in this way natively, with GTM we risk a proliferation of containers (when you may already have many defined), and complicate adjacent development processes (for instance, a stakeholder would need to ensure packages of changes are essentially ‘re-implemented’ when graduating up the testing hierarchy, e.g. from ‘test’, to ‘staging’, and so on all the way up to the final production container).

Final notes / caveats

When exporting/importing containers, we recommend exporting the entire contents of the production container-under-test (as opposed to just your changeset). This means any changes are validated in an environment as close to reality as possible, and helps avoid missing reference errors after importing changes to your ‘test’ container.

In our experience, Charles Map Remotes can occasionally be flaky, taking a few attempts to get working.

Additionally, if you are a 360 customer, you may not want to create an entirely new 360 GTM container just for testing. In this case, a container created using a ‘free’ google account will suffice (although when importing/exporting you’ll need to take care to avoid importing any paid 360 features into your new free container (GTM will complain otherwise).

In your ‘test’ container, we recommend configuring a Custom HTML Tag that runs on every pageview. This tag would include some JavaScript that shows a popup when run. This allows testers to confirm for sure the Charles Map Remote is still working, as failures with this mechanism are non-obvious. If you see the popup for a given pageview, you know the Map Remote worked as expected and you’re on the page with the changeset you expect. If you do not see the popup, you know the Map Remote may not be working and can take steps to check your set up.

Finally, note that Charles offers another feature called ‘Map Local’. Map Local is essentially the same thing as Map Remote, but instead, allows you to serve local files stored on your machine; see these docs.


For more information about how Lynchpin can help solve your data and analytics challenges, please feel free to reach out to a member of our team here.

To keep updated with all of our latest blog posts and news, be sure to follow us on LinkedIn and Twitter.