Google Tag Manager: gtm.dom and gtm.load are missing - google-analytics

I'm implementing the Google Tag Manager script on a clients website.
I'm encountering a random issue: the dataLayer doesn't get its gtm.dom and gtm.load objects.
It only has two Objects, one with a bunch of variables which I'm passing and a dataLoaded event which I'm pushing in.
The issue does appear randomly on different pages, sometimes the dataLayer is correctly filled, sometimes not.
What could be a reason for not getting those two gtm objects?
(note: I'm the one who implements the javascript. The GTM configuration is done by an external contractor)

I found a solution here:
https://productforums.google.com/forum/#!searchin/tag-manager/gtm.load/tag-manager/0Lpevpf2Fss/OMJFuaM04BsJ
I didnt push my variables but assigned them to dataLayer. Its overwritten, so the gtm objects are missing.

The best implementation is assign (not push) variables before tag manager call script.
If you want to use dataLayer.push method, firstly load google tag manager script on the page and
call dataLayer.push in javascript timeout.

Related

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.
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:
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?
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:
And then just reference it in your config tag like so:
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:
and then when you type {{ and start typing the var name in your CJS, you will see this:
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:
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.

Access GTM google tag manager variables from outside of GTM?

I was reading about GDPR and GTM here https://www.analyticsmania.com/post/gdpr-cookie-consent-notification-with-google-tag-manager/
basically how to make GTM gdpr valid.
the issue I saw, was that I don't know how to read any GTM variables from outside of GTM. E.g. in that guide, they store a variable or function that will figure if consent was given or not. How can I read, utilize functions and react to events from outside of GTM?
say I run my little javascript file myapp.js on the page. In there I want to for example not add youtube video embeds in case of they have not given consent. Or add videos and share links if they gave consent. This is not something I can do via GTM obviously.
Well the dataLayer variable is public so you can read it at any time it just might be a little hard to find an specific value since you need to move though an array.
If you want to use a javascript variable on your site as a GTM variable then the variable needs to have global and not local scope (the dataLayer is global but you need to perform a dataLayer.push() to add items to the array).
If the javascript variable on the site is responsible for other site functions and has global scope, then either reference it using a GTM javascript variable or custom javascript variable and use it to act as the trigger exception.
The alternative is to have the site logic prevent the GTM snippet from loading. In the GDPR perfect world, you would have granular opt-out depending on the tags in GTM. You could create a form on site with opt-outs for specific tags, however, that data needs to be stored per customer and delivered to the dataLayer to perform tag specific opt-out functionality.
Can you expand on the logic you are attempting to reference from the site?

Google Tag Manager - (enhanced) e-commerce - how to load Javascript after <body> tag

I'm still learning Google Tag Manager and Enhanced E-commerce tracking, but I have a few questions, some of which may be pretty basic:
We're using a site on a third party system - I already have Google Tag Manager in my template within the HEAD tag, working with Universal (Google) Analytics. However, we want to just get the e-commerce transaction (purchase) data into Analytics - so basic e-commerce tracking would be fine, but I'd rather use Enhanced E-commerce tracking since it is newer - even though my immediate requirement is just to track purchases.
So, I need to send push transaction data into the dataLayer, but I can't do this due to restrictions on the system. I can only add special Javascript code to the end of the BODY tag for my "checkout complete" page.
Reading this online, the dataLayer must be defined in the HEAD before the GTM code is in place. As I cannot do that, I need to load the data using Javascript at the end of BODY.
Is this possible, if so how? I think I can do this using a Custom Javascript Variable as mentioned here: https://developers.google.com/tag-manager/enhanced-ecommerce#macro
Is a "macro" the same as a "variable" as explained in the above link? It says "macro", but Google Tag Manager allows me to define a custom "variable" which is "Custom Javascript". Just checking that these are one in the same.
Where would this code actually "run", if I put it in Google Tag Manager? The third party system defines some variables for me during script execution and I don't know where/when (during page load of the checkout thank-you page) it does it, so to be safe, I'd rather have this script run at the end of the page before the BODY tag closes - if I were doing this manually using plain Javascript within the HTML. In Tag Manager, how would I tell the Javascript to run "at the end of the page"?
Thanks in advance!
1 - Use dataLayer.push() in your Custom Javascript at the end of the BODY. Include an event in this with the transaction data.
For Example:
dataLayer.push( 'event' : 'custom.transaction', 'ecommerce': {} );
You can see the ecommerce object structure here:
https://developers.google.com/tag-manager/enhanced-ecommerce#purchases
dataLayer.push() is used after Google Tag Manager script has been included on the page, so you won't need to define it in the head of the page. Just translate your available ecommerce data into the structure required.
You then need to set up a Custom Event trigger in Google Tag Manager that uses/matches your event value/name.
Then create a Universal Analytics Event Tag that uses this Trigger. Set what ever you would like for the Category, Action and Label. Under More Settings > E-commerce, check Enable Enhanced Ecommerce and then check Use dataLayer.
This event is simply used to pass the Ecomemrce Data into Google Analytics.
2 - Macro is the same as Variable. You are correct Custom JavaScript Variable is what you are after.
3 - The code lives in Google Tag Manager Variable scope and is executed when the variable is used and/or with Google Tag Manager state changes. You can't make this code run at the end of the page. Also this code would need to access/scrape values from the page. To ensure the data is available you would only use this Variable on a Tag that is set to trigger on Window Loaded / DOM Ready, depending on when the on page data is ready.
I would suggest using dataLayer.push() and only use the Custom Javascript Variable approach if dataLayer.push() is not possible.

Google Tag manager not firing the collect url

I am fairly new to GTM and trying to figure out something here.
This is the url where i have set up gtm:
http://pizza.de/order/testshop/5283/index.htm
If you see at console, dataLayer is correctly set. So there is no problem with dataLayer, however i don't see the collect.js url firing. I am very sure that the configuration is correct but not able to figure out why the dataLayer is not being pushed to the server.
Any help will with greatly appreciated.
Move your dataLayer.push code to come before the GTM container tag. You are pushing to the dataLayer afterwards, so the GTM container is not able to use it.
From this:https://developers.google.com/tag-manager/devguide?hl=en
Variables pushed to the data layer (i.e. using dataLayer.push()) after the container snippet will not be able to fire tags on page loads with a matching condition.
#nyuen, was for responding late. Was AFK. Unfortunately, that didn't help. I made a small application running on localhost and tried to create the same scenario.
Variables pushed to the data layer (i.e. using dataLayer.push()) after the container snippet will not be able to fire tags on page loads with a matching condition.
The above is correct, but however i realized that it still fires no matter where you place the dataLayer, but its better to follow the documentation.
What I realized is that, gtm.js is responsible to fire analytics.js and analytics.js is responsible to fire the events. In my case, due to some unknown reason, analytics.js was not loading at all. So I had to inject this script and then the events started firing.

Listeners return different results on different browsers even after clearing cache/cookies

I believe Google Tag Manager is fairly new and nothing much is going on yet. I went all around Google looking for a solution, but simply gave up after trying all possible solutions. I'm using a Wordpress blog platform, and have integrated Universal Analytics and Google Tag Manager. The settings for my listeners are as follows:
====Link Click Listener====
====Outbound Link Click Tagger====
====Outbound Link Rule====
I used console to test the dataLayer, and it retrieves gtm.load, gtm.js and gtm.dom, but regardless of whatever I click, I see on my Google Analytics that the events are undefined even though I provided the necessary parameter to name them. However, when I tried to do it on a different browser, it works, but not completely (instead of outbound link, it will record it under click), or the outbound works for a completely random client on the Internet, returning the tag "outbound-link" but with an undefined action.
Any ideas?
UPDATE I just noticed that there is a difference between a left-mouse-button click and a middle-mouse-button click. The middle one is not measured, whereas the left-mouse-button click is.
For starters there is an error in your rule. You want "{{element url}} does not contain welink.com" instead of just {{url}} (which would mean that the tag should not fire on your domain at all).

Resources