nuxt-community / gtm-module

Google Tag Manager Module for Nuxt.js
MIT License
327 stars 71 forks source link

Page view sends title of previous page #98

Open traubisoda opened 3 years ago

traubisoda commented 3 years ago

Hi,

Any page view event which is triggered by clicking on n-links, are sending the title of the page where the user just navigated away as the pageTitle value (the pageUrl is correct). This also happens if the pageTracking option is set to false in nuxt.config.js, in GA DebugView the page_view events always have the page_title parameter as the title of the referer page. I think this is critical for people who use Google Analytics, as GA displays a majority of things by page title.

Example: I was navigating to the home page from the "About us" page, this showed up in Tag Assistant:

{
  gtm: {
    start: 1608058388699,
    uniqueEventId: 11,
    historyChangeSource: 'pushState',
    oldUrlFragment: '',
    newUrlFragment: '',
    oldHistoryState: {key: '43376.120'},
    newHistoryState: {key: '84313.105'},
    oldUrl: 'http://localhost:3000/',
    newUrl: 'http://localhost:3000/about-us',
    triggers: '1_36',
    gtagReferrer: {G-7V6WM5RSLB: 'http://localhost:3000/'}
  },
  event: 'nuxtRoute',
  routeName: 'index',
  pageType: 'PageView',
  pageUrl: '/',
  pageTitle: 'About us'
}

Does anyone have a workaround for this situation? I am also happy to help if someone points me in the right direction to fix this.

atinux commented 3 years ago

It is weird since it does send in router.afterEach + a setTimeout: https://github.com/nuxt-community/gtm-module/blob/master/lib/plugin.js

Do you have a small reproduction or your current website using GTM module?

traubisoda commented 3 years ago

Sorry, sadly I cannot link my current code. But I dug into the module code last night, and saw that the timeout is set to 250ms. In my case, a navigation takes longer than that on some pages. I copied the startPageTracking function to a separate plugin, and raised the timeout to 2 seconds, after that the page title was sent correctly.

My current workaround is:

I think a reliable way to make page tracking work automatically would be if we could somehow react to a page mount from the router, or if on navigation, the push state would happen only after the meta/head updates. The latter would be super nice, because then the GA4 enhanced events could pick up those history changes as page views (currently this has the same problem, it picks up the wrong title).

atinux commented 3 years ago

Are you using the fetch() hook to fetch data if your pages or asyncData?

traubisoda commented 3 years ago

Mostly in asyncData, but I'm experiencing the title issue on pages without asyncData or fetch too.

atinux commented 3 years ago

Normally with asyncData it should be fine since it is blocking vue-router so afterEach will have the correct data.

I can happen if you are using fetch (non blocking on client-side) or any other Vue hooks (beforeMount, mounted).

For this, I suggest to call manually gtag once your data has been fetched if your head depends on the data.

traubisoda commented 3 years ago

My page titles mostly don't depend on asyncData or fetch, they are typed in the head() of the page components. Is this maybe a bad practice?

What I observed, is that in universal mode, when I click on an n-link to navigate to a page, these steps are happening in this order:

  1. Click on n-link
  2. URL changes to the next page's URL, next page starts to load
  3. View event fired in afterEach, page title hasn't changed yet
  4. Page title is updated
atinux commented 3 years ago

Do you have an example of the page using head ?

traubisoda commented 3 years ago

Sure! Here are the two pages, which I used as an example in the opening comment: https://gist.github.com/traubisoda/d5a83eeb7a02e77bcad5def857d27927

atinux commented 3 years ago

Do you mind sharing also the ~/mixins/pageview.js file please?

traubisoda commented 3 years ago

I added it to the gist: https://gist.github.com/traubisoda/d5a83eeb7a02e77bcad5def857d27927

atinux commented 3 years ago

Actually $metaInfo is undefined.

Can you try to read the title with this.$meta().refresh().metaInfo.title in your mixin?

export default {
  // mounted is called only on client-side
  mounted() {
      this.$nextTick(() => {
        this.$gtag('config', process.env.googleAnalyticsId, {
          page_title: this.$meta().refresh().metaInfo.title,
          page_path: this.$route.fullPath,
        })
      })
  },
}
traubisoda commented 3 years ago

Hmm, that's strange, it's not undefined for me. Did you maybe use head: {...} and not head() {...} in your page? Your code works for both cases though :)

atinux commented 3 years ago

Does this solves your issue?

traubisoda commented 3 years ago

Well I kinda already worked my way around the issue with the pageview.js, the issue that I opened was regarding the original auto tracking feature of the gtm-module.

OrkhanAlikhanov commented 2 years ago

It seems when afterEach called, sometimes the page is not mounted yet and 250ms is not always enough for a page to mount. Thus this issue happens

rmarmitt commented 1 year ago

It seems when afterEach called, sometimes the page is not mounted yet and 250ms is not always enough for a page to mount. Thus this issue happens

Exactly, the same thing happens here. Occasionally, the title of the previous page is keped.

I believe that the timeout should be customized, so for these cases we could increase the 250ms to something more suitable.

https://github.com/nuxt-community/gtm-module/blob/ae9199e6cab39485bcc85758bdfb36ebace3cdcf/lib/plugin.js#L68-L76