Search code examples
google-analyticsgoogle-tag-managergoogle-analytics-4

Prevent Google Tag Manager from firing tag on localhost


I've successfully installed Google Tag Manager on my website. I've started firing some events from Google Tag Manager and can see them come up when using the tag assistant debugger. I've set up tags which send events to Google Analytics and can see that data pipeline working well.

enter image description here

What I'd like to do is have an easy way to configure all my tags of type GA4 Event to not fire when the trigger happens in a non-production environment. I'd like my triggers to work in non-production environments (so that I can debug my triggers), I just don't want the events to be piped to Google Analytics in non-production environments. Is there an easy way to set that up in Google Tag Manager?

I've noticed that when running the tag assistant debugger there's a field called debug_mode which is set to true. I tried setting that in my local environment like so:

export function maybeSetDebugMode() {
  if (typeof window !== 'undefined' && process.env.NODE_ENV !== 'production') {
    window?.dataLayer?.push({"debug_mode": "true"})
  }
}

but it seems that even with this code, my custom events continue to get piped to GA:

enter image description here

Broadly speaking, is there a way to configure Tag Manager to not pipe events to GA when a certain condition is met (like a URL match or some other event field having a specific value)? Alternatively, can Google Analytics be configured to ignore events during ingestion which meet some criteria?


Solution

  • Yes, there are pretty elegant solutions for not sending events to your prod GA from lowers or from previewing/debugging. And yes, there is a way to prevent GA from accepting those events.

    I'll start from the former since it's much more proper.

    Typically, to start sending events to GA4 from GTM, you have to have at least one GA4 configuration tag that asks you for the measurement id. Well, no one forces you to just give it the measurement id. Give it a CJS instead:

    enter image description here And then just reference it in your config tag like so: enter image description here

    Generally, this should do what you want. Whenever you're in your lower env, or when hostname is localhost, well or 127.0.0.1, or when you're previewing the container on prod, or whatever else you feel proper there, you will see your tags and triggers firing, but your associated events will be flowing into a different GA4 property.

    About that different GA4 property. It is a good practice to still collect your lower env events rather than sending them to a non-existent property. There will be time when you want to see some testing data. Just don't keep it in one property with your prod data, but you know that.

    Ok, now let's move to the second option. GA4, of course, has data filters. The filters are premature comparing to the old filtering system in GA UA like most of the GA4 features, however, they somewhat fit your needs. In particular, the developer traffic filter. You'd have to add a custom parameter to every developer event that you would like to be visible in debug view, but not present in the reports.

    Given how raw and buggy GA4 is and how the number of filters in there is now severely limited, I would advise to solve it in GTM and keep the filters for things that couldn't be solved through GTM. Things like analytics spam, if you ever get it.

    GTM has built-in vars that you can reference. But most of them are disabled by default. Here:

    enter image description here

    and then when you type {{ and start typing the var name in your CJS, you will see this:

    enter image description here

    just click the option that you need and it'll autofill for you.

    and you're supposed to treat it as whatever that referenced variable returns. It's mostly strings. but you can definitely return a funciton and run it like {{cjs that returns a function}}(param1, param2). Anyhow, we're doing strings, so, here:

    enter image description here

    should be pretty comfy to use. The only awkward thing with referencing the built-in vars is that it's hard to debug them in the console, so I often just take my hostname from globals, like window.location.hostname.