Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
darkylmnx opened this issue Sep 2, 2018 · 27 comments

Comments

@darkylmnx
Copy link

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?

@darkylmnx darkylmnx changed the title title resolving after router's "afterEach" hook, making analytics.js / gtag.js pageviews, bug title resolving after router's "afterEach" hook, making analytics.js / gtag.js pageviews incorrect Sep 2, 2018
@Nabellaleen
Copy link

Same problem for me :/ Any tips ?

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

@hecktarzuli
Copy link

hecktarzuli commented Mar 5, 2019

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: vuejs/vue-router#1197

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

@pimlie
Copy link
Collaborator

pimlie commented Mar 6, 2019

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
Copy link

@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
Copy link
Author

darkylmnx commented Mar 6, 2019 via email

@hecktarzuli
Copy link

hecktarzuli commented Mar 6, 2019

@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
Copy link
Collaborator

pimlie commented Mar 6, 2019

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
Copy link
Author

darkylmnx commented Mar 6, 2019 via email

@darkylmnx
Copy link
Author

darkylmnx commented Mar 6, 2019 via email

@hecktarzuli
Copy link

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
Copy link
Author

darkylmnx commented Mar 6, 2019 via email

@pimlie
Copy link
Collaborator

pimlie commented Apr 20, 2019

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
Copy link

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

@reinoldus
Copy link

Is the afterNavigation function implemented somewhere?

@tkd-itsuki
Copy link

same issue , anyone with a good fix?

@pimlie
Copy link
Collaborator

pimlie commented Jun 10, 2020

@tkd-itsuki
Copy link

tkd-itsuki commented Jun 10, 2020

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
Copy link
Collaborator

pimlie commented Jun 10, 2020

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
Copy link

tkd-itsuki commented Jun 10, 2020

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

@pimlie
Copy link
Collaborator

pimlie commented Jun 10, 2020

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
Copy link

@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
Copy link
Collaborator

pimlie commented Jun 10, 2020

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

@nathanchase
Copy link

nathanchase commented Jun 23, 2020

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
Copy link

nathanchase commented Jul 16, 2020

@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:
nuxt-community/gtm-module#36
nuxt-community/gtm-module#38
nuxt-community/google-analytics-module#8

@leotuna
Copy link

leotuna commented Apr 23, 2021

Were you guys able to solve this?

@fmoessle
Copy link

Any updates?

@Rigo-m
Copy link

Rigo-m commented Feb 27, 2024

Posted the solution for nuxt 3 here:
vuejs/vue-router#1968

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants