nuxt / vue-meta

Manage HTML metadata in Vue.js components with SSR support
https://vue-meta.nuxtjs.org
Other
4.08k stars 247 forks source link

title resolving after router's "afterEach" hook, making analytics.js / gtag.js pageviews incorrect #259

Closed darkylmnx closed 5 years ago

darkylmnx commented 6 years ago

I'm trying to track page vues using gtag.js, and as a simple case, I just added the pageview in an afterEach hook of the router, but the title seems to be resolved later (I guess because of the batch update performed).

This delay messes up pageview titles.

Is there a way to know when the meta title is resolved?

Nabellaleen commented 5 years ago

Same problem for me :/ Any tips ?

I didn't found any available hooks in vue-meta

hecktarzuli commented 5 years ago

Same here. But I think it's larger than this, if you look at window.location.href, it's even the old url too.. ie, it may not have anything to do with vue-meta and everything to do with listening to the right event (vs afterEach).. I'll post here if I find the answer.

Related: https://github.com/vuejs/vue-router/issues/1197

I ended up saying 'screw it' and just put in a setTimeout of 500ms :(

pimlie commented 5 years ago

In the next branch I have added an afterNavigation hook which will at least solve the document.title issue

@hecktarzuli Shouldnt the window.location.href be updated once the DOM is updated?

hecktarzuli commented 5 years ago

@pimlie in theory yes. I was talking more about the first comment. If @darkylmnx is using afterEach for GA, he may want to verify the urls being sent are correct. In my project, they weren't :( A simple console.log(window.location.href) just before your GA hit should give you a clue.

darkylmnx commented 5 years ago

In mine they are randomly correct depending on many things.

We need to find a hook that actually knows if the component is rendered, afterEach doesn't seem to do that so the question is where yo globally send GA pageviews ?

For now I'm manually sending it in all my page components but it's cumbersome and repetitive

Le mer. 6 mars 2019 à 18:21, Josh Deltener notifications@github.com a écrit :

@pimlie https://github.com/pimlie in theory yes. I was talking more about the first comment. If @darkylmnx https://github.com/darkylmnx is using afterEach for GA, he may want to verify the urls being sent are correct. In my project, they weren't :( A simple console.log(window.location.href) just before your GA hit should give you a clue.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nuxt/vue-meta/issues/259#issuecomment-470196821, or mute the thread https://github.com/notifications/unsubscribe-auth/ABXDteFv0u6w5VZxMjFY4o8REV9ZW8XWks5vT_kogaJpZM4WWbSY .

hecktarzuli commented 5 years ago

@darkylmnx GA doesn't have to be instant. There is an outstanding bug in vue-router that posa will work on once he gets time to make sure afterEach is called after the url is resolved. In the meantime, I'd just use a timeout of ~ 500ms and call it a day :)

pimlie commented 5 years ago

Did you look at vue-analytics?

Anyway, the afterNavigation hook I added is the only one that will work probably because vue-meta will always asynchronuously update the headers which means that no vue-router hook will ever be sufficient.

If you need it fixed now, add a beforeEach hook and trigger the GA in the first vue-meta changed callback after that beforeEach hook has run. I used that scheme in my nuxt-matamo plugin to track pages and havent seen any issues with that

darkylmnx commented 5 years ago

Well that's what I did at some point but there are issues with lazy loading components it's seems so I just did it in each page and it's okay.

Le mer. 6 mars 2019 à 18:34, Josh Deltener notifications@github.com a écrit :

@darkylmnx https://github.com/darkylmnx GA doesn't have to be instant. There is an outstanding bug in vue-router that posa will work on once he gets time. In the meantime, I'd just use a timeout of ~ 500ms and call it a day :)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nuxt/vue-meta/issues/259#issuecomment-470201588, or mute the thread https://github.com/notifications/unsubscribe-auth/ABXDtSOOzg_92bJq0UufGGxKg-zC3GgQks5vT_wsgaJpZM4WWbSY .

darkylmnx commented 5 years ago

Vue+analytics has the same issue and randomly send the title of the previous page from time to time. It seems to be complicated to find a way to fix this as this is related to the vue-meta update timing.

Le mer. 6 mars 2019 à 18:36, Pim notifications@github.com a écrit :

Did you look at vue-analytics?

Anyway, the afterNavigation hook I added is the only one that will work probably because vue-meta will always asynchronuously update the headers which means that no vue-router hook will ever be sufficient.

If you need it fixed now, add a beforeEach hook and trigger the GA in the first vue-meta changed callback after that beforeEach hook has run. I used that scheme in my nuxt-matamo plugin to track pages and havent seen any issues with that

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nuxt/vue-meta/issues/259#issuecomment-470202420, or mute the thread https://github.com/notifications/unsubscribe-auth/ABXDtXmD8tl0HCghpqkYL2tY62UbhsoMks5vT_y2gaJpZM4WWbSY .

hecktarzuli commented 5 years ago

Are you hitting GA directly, or are you going through Google Tag Manager? If GTM, you could just use a custom event vs the internal 'history changed' trigger. That's what solved our problems. It also doesn't help that route changes trigger on load when they really don't, thus you get double first page hits quasi-randomly.

darkylmnx commented 5 years ago

No I'm using gtag.js directly which is like hitting GA directly. I'm not using GTM.

Le mer. 6 mars 2019 à 18:42, Josh Deltener notifications@github.com a écrit :

Are you hitting GA directly, or are you going through Google Tag Manager? If GTM, you could just use a custom event vs the internal 'history changed' trigger. That's what solved our problems. It also doesn't help that route changes trigger on load when they really don't, thus you get double first page hits quasi-randomly.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nuxt/vue-meta/issues/259#issuecomment-470204363, or mute the thread https://github.com/notifications/unsubscribe-auth/ABXDtVwzGp4dlH28-v9ZW3azv46sZCajks5vT_4BgaJpZM4WWbSY .

pimlie commented 5 years ago

This issue has been closed as changes for it are included in the v2 release candidate. Please help us testing the release candidate and report any follow-ups in a new issue

hecktarzuli commented 5 years ago

We'll have to check it out, thank you!

reinoldus commented 5 years ago

Is the afterNavigation function implemented somewhere?

tkd-itsuki commented 4 years ago

same issue , anyone with a good fix?

pimlie commented 4 years ago

@itsukiuehara Use https://vue-meta.nuxtjs.org/api/#afternavigation and/or https://vue-meta.nuxtjs.org/api/#refreshonceonnavigation

tkd-itsuki commented 4 years ago

thanks @pimlie , I tried the above documentation. any idea on why the afterNavigation won't work under the head()? I'm trying to auto track the page_views by creating a plugin called vue-gtag.js, but the title I am getting there is the title from nuxt.config.js

index.vue


  head() {
    return {
      title: "title I want to send to GA",
      afterNavigation(metaInfo) {
        console.log("entered afterNavigation")
        trackPageView(document.title)
        // is the same as
        trackPageView(metaInfo.title)
      }
    }
  },```

plugins/vue-gtag.js
```export default ({ app: { head, router } }, inject) => {
  // Add script tag to head
  head.script.push({
    src: `https://www.googletagmanager.com/gtag/js?id=XXXXXXXX`,
    async: true
  })
  console.log("added script")

  // Include Google gtag code and inject it (so this.$gtag works in pages/components)
  window.dataLayer = window.dataLayer || []
  function gtag() {
    dataLayer.push(arguments)
  }
  inject("gtag", gtag)
  gtag("js", new Date())

  // Add tracking codes from Vuex store
  gtag("config", "XXXXXXXX", {
    send_page_view: false // necessary to avoid duplicated page track on first page load
  })

  console.log("installed code XXXXXXXX")

  // After each router transition, log page event to Google for each code
  router.afterEach(to => {
     gtag("config", "XXXXXXXX", {
       page_title: "title I want to send to GA ",
       page_path: to.fullPath
     })
  })
}```
pimlie commented 4 years ago

Tracking document titles can be unreliable when using transitions. Try to add a $nextTick or something.

Also you are still calling router.afterEach in the vue-gtag plugin, so dont get confused with that.

tkd-itsuki commented 4 years ago

@pimlie what are your suggestions for tracking document titles besides afterEach if I would do it inside a plugin ?

pimlie commented 4 years ago

router.afterEach runs before the transition has finished so before your new page has been fully loaded. You could try to run in vue-meta's afterNavigation hook, that will also make sure the meta data only gets updated after the navigation/transition has finished. But that also isnt super reliable unfortunately (eg FF sometimes delays updating the title), so you could still need to do a $nextTick.

tkd-itsuki commented 4 years ago

@pimlie I can't find a way to access vue-meta's afterNavigation hook on my plugin, do you mind showing a snippet on how I can achieve the above result?

pimlie commented 4 years ago

Untested but it should be possible to use addApp in your plugin and add a afterNavigation hook with that.

nathanchase commented 4 years ago

I've been trying to figure out how to access addApp from within the app context, but I can't seem to figure it out. I'm trying to hook into afterNavigation from within the gtm-module, because it suffers from the same issue where page tracking occurs before the page meta has rendered, and sends along false data when its pageview event fires.

How exactly would one access afterNavigation from inside a Nuxt module?

nathanchase commented 4 years ago

@pimlie @itsukiuehara Did you ever find a solution to this issue (which shouldn't be closed, btw)? Page tracking is still occurring before page meta renders.

Related: https://github.com/nuxt-community/gtm-module/issues/36 https://github.com/nuxt-community/gtm-module/issues/38 https://github.com/nuxt-community/analytics-module/issues/8

leotuna commented 3 years ago

Were you guys able to solve this?

fmoessle commented 1 year ago

Any updates?

Rigo-m commented 8 months ago

Posted the solution for nuxt 3 here: https://github.com/vuejs/vue-router/issues/1968