Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GTM randomly skips initial pageview in single page app

I have Pageview tag in Google Tag Manager that tracks SPA pageviews, identical to the one described in this guide. Basically it is Universal Analytics with linked Google Analytics ID that is triggered on History Change (at some point All Pages trigger was also added with no success).

In my current app GTM skips Pageview tag on initial pageviews on all routes that don't have async resolvers. Usually the routes fire the tag sometimes (1 of 5 times), this may vary a bit depending on conditions (cached vs uncached, localhost vs production).

On the routes that have resolvers with long durations (> 1s) Pageview tag is always fired on initial pageviews (5 of 5 times).

Pageview tag is fired normally on all routes after app initialization (pushState).

This behaviour was confirmed with GTM debug console and GA realtime monitoring.

The setup seems to be the recommended one, GTM snippet is loaded in <head>, Angular 2 app is loaded at the end of <body>.

<html>
  <head>
    <script>/* Google Tag Manager snippet */</script>
    ...
  </head>

  <body my-app>
    ...
    <script src="my-app-bundle.js"></script>
  </body>
</html>

And Angular 2 is bootstrapped like usual:

platformBrowserDynamic().bootstrapModule(MyAppModule);

I've tried to move GTM snippet all around, before and after my-app-bundle.js, even replace it with synchronous:

<script>
  window.dataLayer = ...
</script>
<script src="https://www.googletagmanager.com/gtm.js?id=..."></script>

There was no difference with default snippet.

I've found by trial and error that Pageviews start to work normally on initial pageviews if the app is bootstrapped with considerable delay, 200-1000ms (it seemed at first that DOMContentLoaded does the trick but the delay wasn't enough):

setTimeout(() => {
  platformBrowserDynamic().bootstrapModule(MyAppModule);
}, 1000);

I hope that this problem is familiar to the experts who've done GTM with SPA/Angular 2 applications. Unfortunately, I cannot provide MCVE for this case but I believe it can be replicated with any Angular 2 (2.3.1) app with routing and Google Tag Manager account.

Usually Angular 2 apps can be safely bootstrapped at the end of <body>.

What is going on there and how pageview tracking should be properly handled with GTM without race conditions?


UPDATE: When switching from GTM to using GA directly with

router.events.subscribe(e => {
  if (e instanceof NavigationEnd)
    ga('send', 'pageview', location.pathname);
})

everything works fine on initial and subsequent pageviews with no race conditions.


UPDATE 2:

Here's a timeline of how it looks in the case of success with long-running route resolver, gtm.js and main.bundle.js are loaded in the beginning (it doesn't matter in which order), analytics.js (analytics_debug.js when GA Debugger is on) is loaded when route resolver completes and Pageview tag is fired, i.e. after ~10s:

like image 720
Estus Flask Avatar asked Jan 14 '17 21:01

Estus Flask


People also ask

Why are my GTM tags not firing?

Sometimes a tag is not firing where it should because of multiple triggers or multiple rules within a trigger. The Solution: As all tags fire as a result of trigger configurations, this is normally the best place to start when tags are not firing as intended. Start by double checking your trigger settings.

How do I track pageviews in GTM?

In order to track clicks on a form submit button via virtual pageviews in GTM, you need to do the following: #1 Find the web page which contains the form and note down the URL. #2 Find the ID attribute of the form. #3 Create a trigger in GTM which can check click on the form submit button.


1 Answers

As @kemsky suggested, GTM lifecycle is tied to internal gtm.load event, which happens on window onload. So DOMContentLoaded may be too early to bootstrap.

Considering that GTM script was loaded prior to SPA script,

window.addEventListener('load', () => {
  platformBrowserDynamic().bootstrapModule(MyAppModule);
});

callback will be triggered when GTM is ready to receive history change events, and there should be no race conditions.

like image 146
Estus Flask Avatar answered Sep 17 '22 20:09

Estus Flask