In this article, I’m going to tackle one of the most frequently asked questions out there:

Can you run Google Analytics using the snippet AND using a Google Tag Manager Tag on the same page?

There are many facets to this query, so I’ll try to tackle as many of them as I possibly can.

First, a terminology rant. You hear lots of talk about “on-page” and “inline” Google Analytics tracking, as that’s what’s used to describe the non-GTM way of tracking Google Analytics. Well, all the power to you, but I think they’re just adding to the confusion. GTM is just as “on-page” and “inline” as GA’s own snippet, as both are based on injecting an asynchronous HTTP request that downloads the respective library.

I’ve chosen to use snippet-based tracking to describe Google Analytics tracking that’s outside GTM, and Tag-based tracking to describe Tags run through GTM. Note the capital ’T’, as that’s the syntax I most commonly use in this blog to denote Google Tag Manager assets.

I’m fully aware this distinction can cause confusion as well, but since I’d hesitate to ever call the ga('send',...) commands on the page “tags” of any kind, I think this makes a bit more sense.

The premise: what the problem really is

Most often this question gets asked when migrating to Google Tag Manager. There was a crazy amount of questions about this in the Google Tag Manager Fundamentals course forums, where I was volunteering my help. There were so many questions about it that I felt the need to write the following intro to course participants:

I don’t know if it helped, but at least it let me jot some things down that would be helpful to anyone pondering about these issues.

The problem itself is usually a manifestation of the following, underlying queries:

  1. Will just adding Google Tag Manager to the site break my existing Google Analytics tracking?

  2. Will adding a Google Analytics Tag in GTM break my existing Google Analytics tracking?

  3. Can I run the bulk of my tracking via the Google Analytics snippet, and use Google Tag Manager Tags for tracking certain specific things?

  4. Can I run the bulk of my tracking via Google Tag Manager, and use ga('send',...) commands on the page to cover some, usually legacy, tracking needs?

  5. I’m just curious, how does snippet-based tracking differ from GTM’s Tag-based tracking?

The last question is just the best, I can’t wait to get to it!

OK, I’ll start with it! That’s how crazy and unpredictable I am.

5. Snippet-based vs. Tag-based tracking

When you create your Google Analytics tracker using the given snippet, you have the option of providing a tracker name vs. using the default name.

For example, if you want to name the tracker SuperTracker, you’d use the following syntax in the tracker creation command:

ga('create', 'UA-12345-1', {'name' : 'SuperTracker'});

This would give the tracker a name, after which you interact with it by prefixing all commands sent to the ga() queue with the tracker name: ga('SuperTracker.send', 'pageview);.

If you don’t provide a tracker name, you can use the naked ga('send',...) syntax, where you don’t use a tracker name prefix. However, the tracker does have a name: t0 (t-zero). So the following two commands do the same thing:

ga('send', 'pageview');
ga('t0.send', 'pageview');

This is clear, yes? The reason you’d want to rename the tracker is if you’re running multiple trackers on the page, or due to some very special edge cases I might or might not touch upon later in the article (I’m just making this stuff up as I go along).

Now, with Google Tag Manager it’s a bit different. In GTM, whenever a Tag is injected, i.e. whenever a Tag “fires” (hate that terminology as well) due to some Trigger “firing” as well, a new tracker is created with a random, unique name:

So here the GTM tracker was created with the name gtm1454402957304. For you fellow nerds, look at the numbers in that string. Don’t they look vaguely familiar? That’s right, it resembles Unix time! So, in fact, the tracker name isn’t random, it’s just the exact timestamp of when the tracker was created, down to the millisecond. So it’s not deterministically unique, either, but having two Tags fire at the exact same millisecond is, as far as I know it, next to impossible.

So, now the major difference is spelled out for you: the GA snippet requires that you either use a fixed, default tracker name when creating the tracker, or you give it a custom name. This tracker name is then used when communicating with the tracker object.

GTM, on the other hand, creates a new, unique tracker name for every single Tag on the page - even when the same Tag is injected multiple times.

This is, in fact, how GTM manages to navigate through one of the biggest flaws of the platform. I’ve outlined this in a previous article on the dangers of messing with the tracker name setting in GTM’s GA Tags. In a nutshell, GTM doesn’t let you assign settings, fields, custom dimensions and the ilk on the hit itself, but they’re always set on the tracker object. This means that they are “hit-scoped” by default, since each Tag has its own tracker, but if you mess with the tracker name you’ll run into some unexpected side effects.

Now that we have the basics sorted out, let’s jump into the queries themselves.

1. Will Google Analytics break if just Google Tag Manager is installed on the page?

This is easy to answer:


Remember, Google Tag Manager has nothing to do with Google Analytics when you add the container on the page. It’s just a container, a chassis, a receptacle, a vehicle, a vessel (making the most out of my thesaurus here) for your Tags and other arbitrary JavaScript you want to execute on the page.

When you add the Google Tag Manager container snippet to the page, all it does is load a library from Google servers. It doesn’t create any Google Analytics trackers, it doesn’t mess with your tracking code, it doesn’t interfere with other JavaScript running on the site, or anything like that.

In other words, feel free to add the container snippet to the page the minute you’ve created the container.

2. Will adding a Google Analytics Tag in GTM break my existing tracking?

This is also easy to answer:


Now, choose your favorite conjunct: “However…” / “But…” / “Unless…”. I’ll go with the first one.

However, if you’ve manually set the Google Tag Manager tracker name to the GA tracker name, and you don’t know what you’re doing, problems can arise.

I’ve covered many of these cases in my tracker name rant.

The most important thing to note is that if the tracker name is shared between the snippet-based tracker and GTM’s Tag, each time a new tracker is created on the page (usually via GTM) with that name, any settings it has will overwrite all the previous settings on any of the trackers.

So, for example, let’s say you’ve created the snippet-based tracker with:

ga('create', 'UA-12345-1');

And then you set the Tracker name in GTM to blank:

Now, since you only create the tracker once when using snippet-based GA tracking, any GTM Tag that shares the tracker name and fires after the snippet-based tracker will overwrite all the settings that were in the snippet-based tracker.

So, let’s say you’re tracking to UA-12345-1 in the snippet, using the ga('create','UA-12345-1') command to create the tracker. Then, you have an Event Tag in GTM, collecting data to ‘UA-12345-2’, and firing after 15 seconds of dwell time on the page. If this Tag has the same tracker name as the snippet-based tracker, any ga('send',...) commands you run on the page after this GTM Tag has fired will now use the settings in the GTM Tag, including the new property ID.

You can see how this is potentially a huge problem.

But like I wrote in the beginning of this chapter, if you don’t mess with the tracker name setting, there will be no interference. You can freely track via Google Tag Manager to a Google Analytics property, and then keep the snippet-based tracker collecting data to some other property, if you wish.

This is a great segue to the next question.

3. Run the bulk of tracking via the snippet, and use GTM for specific things

In this case, we want to combine snippet-based GA tracking with Google Tag Manager Tags.


Well, it’s certainly doable. You can easily have a snippet-based tracker track to UA-12345-1, and then add the occasional Tag via GTM to also track to UA-12345-1, and you don’t have to make any changes if working with default settings. Google Analytics uses a combination of Client ID found in the _ga cookie together with the UA-XXXXX-Y code to make sure hits are attributed to the same session and the same user.

There are some cases where you will need to make changes:

  • If you’re using custom cookie settings in either, make sure they match between the snippet-based tracker and all the Google Analytics Tags you’re running via Google Tag Manager into the same GA property.

  • If you’re using custom traffic source tracking, make sure you respect these in all the Tags and snippet commands sending data to the same Google Analytics property. For example, if you GA snippet is sending the ?utm-parameters with the page URL, but in GTM you’re overwriting the page name with something customized, it’s possible the GTM Tag will use the referrer instead, creating a new session since the traffic source changed.

All in all, try to make all fields and settings match between the trackers. This way you won’t run into surprises when one creates a session and the other one creates a new session immediately after due to a discrepancy in the tracker settings.

4. Using GTM to drive tracking, and occasionally resorting to snippet-based commands

This is a tricky one. Usually it’s because there’s a huge, sprawling legacy library for snippet-based tracking, and the user wants to migrate one command at a time.

The easiest way to make it work is to remember to have the Google Analytics snippet and tracker creation commands on each page as before. If you do this, there won’t be any conflicts as long as you respect the tips in the previous chapter.

However, if you’re in a jam where you only have a ga('send',...) command here or there, without any tracker creation via the snippet, things get much more complicated. To make it work, the following things need to happen:

  1. The ga('send',...) cannot be run before the first GTM Tag has been added to the page. Before that, the ga() function doesn’t exist in the global namespace.

  2. The Google Tag Manager Tag needs to have its Tracker Name setting set to blank (if you’re using ga('send',...) on the page), or to a custom name, in which case the snippet-based commands need to use that name as well: ga('customName.send',...).

The first one is very difficult to respect, since the Google Tag Manager is downloaded asynchronously. To mitigate this, you can add this line to the <head> of each page, before any ga() functions are called:

  window['GoogleAnalyticsObject'] = 'ga';
  window['ga'] = window['ga'] || function() {
    (window['ga'].q = window['ga'].q || []).push(arguments)

This is taken from the Universal Analytics snippet, and it basically creates a temporary data store for all ga() commands that exist before the analytics.js library has been created.

If you take all the previous tips into account, then there should be minimal problems with combining tracking methods like this. However, it’s still suboptimal, and can lead to unexpected problems due to the complexity of the code you need to manage and maintain.


What started as a simple foray into tracker discrepancies blossomed into a sprawling, overly complex account of how tracking works across the Google Analytics snippet and Google Tag Manager’s Tag templates.

Bottom line is, if you do want to combine tracking across the two methods, you need to make sure that tracker settings match across the board.

On the other hand, if you want to track each tracker method to a different Google Analytics property, you need to make sure that certain tracker settings do NOT match across the trackers.

All in all, you’ll commonly hear people suggesting that you move to Google Tag Manager in all your tracking needs. I tend to agree in general, but there are many, many solid reasons for keeping the snippet-based tracker, at least for a little while.

Whenever I do a migration from snippet-based to Google Tag Manager -based tracking, I run the two simultaneously (to different properties) until I’m satisfied the migration has been a success.

Similarly, it’s not an altogether bad idea to keep the snippet-based tracker on the page for a while, just so you can benchmark the two different tracker setups in your data, and perhaps use the information to improve overall data quality.