nuxt-community / google-analytics-module

Google Analytics Module for Nuxt 2
https://google-analytics.nuxtjs.org/
MIT License
637 stars 53 forks source link

Timing issue with vue-meta #8

Closed cbodin closed 4 years ago

cbodin commented 6 years ago

pageviewTemplate is resolved before vue-meta has synced the page components head.

Reproduce:

  1. Download Nuxt.js starter template

  2. Install analytics module and set pageviewTemplate:

    // nuxt.config.js
    'google-analytics': {
    id: 'UA-XXXXXX',
    debug: {
    enabled: true,
    },
    autoTracking: {
    pageviewTemplate: route => {
      return {
        page: route.path,
        title: document.title,
        location: window.location.href,
      };
    },
    },
    },
  3. Setup two pages:

<!-- pages/page1.vue -->
<template>
  <div>
    <h1 class="title">Page 1</h1>

    <div class="links">
      <nuxt-link to="page1">Page 1</nuxt-link>
      <nuxt-link to="page2">Page 2</nuxt-link>
    </div>
  </div>
</template>

<script>
export default {
  head() {
    return {
      title: 'Page 1',
    };
  },
}
</script>
<!-- pages/page2.vue -->
<template>
  <div>
    <h1 class="title">Page 2</h1>

    <div class="links">
      <nuxt-link to="page1">Page 1</nuxt-link>
      <nuxt-link to="page2">Page 2</nuxt-link>
    </div>
  </div>
</template>

<script>
export default {
  head() {
    return {
      title: 'Page 2',
    };
  },
}
</script>

Expected behavior: Page 1 will track "Page 1" as title Page 2 will track "Page 2" as title

Actual behavior: Page 1 & Page 2 tracks title correctly during initial load Page 2 tracks "Page 1" when changing route from Page 1 -> Page 2 Page 1 tracks "Page 2" when changing route from Page 2 -> Page 1

Console output:

location         (&dl)   http://localhost:3000/page2
page             (&dp)   /page2
title            (&dt)   Page 1
location         (&dl)   http://localhost:3000/page1
page             (&dp)   /page1
title            (&dt)   Page 2
This question is available on Nuxt.js community (#c8)
failpunk commented 6 years ago

I just installed this for the first time and it's doing the same thing. It's tracking the previous pages meta information when changing routes.

failpunk commented 6 years ago

@cbodin Did you find any solution to this? Out of the box this plugin DOES NOT track pageviews correctly. For me the page title (dt ga field) is not being updated before the GA collect call is made...it is sending the title from the previous page.

cbodin commented 6 years ago

@failpunk I used the Tag Manager module and added page tracking via the tag manager interface: https://github.com/nuxt-community/modules/tree/master/packages/google-tag-manager

MatteoGabriele commented 6 years ago

@cbodin I've made a small refactoring and I think it might fix this issue. Please let me know if it does so we can close the ticket :)

Just make sure the plugin is downloading vue-analytics version 5.10.5 as a dependency

thanks

failpunk commented 6 years ago

@MatteoGabriele This is still an issue:

Versions: vue-analytics@^5.4.0 @nuxtjs/google-analytics@^2.0.2

Below are the results being sent to: https://www.google-analytics.com/collect

1) initial pageview: to /blog

dl: http://localhost/blog
dp: /blog
dt: Blog - Advice and Planning Blog

2) Client-side navigate to: to /waitlist

dl: http://localhost/blog
dp: /waitlist
dt: Blog - Advice and Planning Blog

It's still tracking the incorrect title.
I can confirm this in the GA dashboard. Titles DO NOT match the path...which makes this data incorrect.

I appreciate the hard work but this is not a production-ready plugin until we can correct this.

MatteoGabriele commented 6 years ago

hi @failpunk as you can see from the previous post, you're not using the latest version, which by now is 5.10.6, but I still see that problem.

The thing is that I don't know when the new page is fully rendered other than use a nextTick as a reference. This works for normal SPA applications, but for SSR is kinda tricky. The only solution I have found is to add a timeout of 100ms before tracking the next route, which makes me feel dirty ahahahhahaha

@pi0 is there a way to know in Nuxt or Vue when the next page is rendered?

thanks

failpunk commented 6 years ago

Apologizes @MatteoGabriele, I put the package.json version, I can see yarn resolved the library to 5.10.6 in the .lock file. The main issue with Nuxt is that is does not resolve the meta data before all of the router hooks have already fired. They are going to have to change that at some point of we'll always have this issue. I'm not sure who to have a conversation with about this.

MatteoGabriele commented 6 years ago

No worries :) I was trying to create a proxy for the rendering process applying nextTick by default and maybe using the method called renderRoute for Nuxt, but I'm not sure if it is going to work.

hopefully, @pi0 might help me with that or I'll drop a ticket in the Nuxt repo.

MatteoGabriele commented 6 years ago

Just to update you: I've opened a ticket a few days ago but still no answer.

Let's wait a bit more :)

cbodin commented 5 years ago

Any updates on this issue?

MatteoGabriele commented 5 years ago

Nope! Sorry. More then opening a separate ticket for some answers I can't do much :)

cbodin commented 5 years ago

Cool, maybe we should open an issue in the vue-meta repo? :) I've however found a workaround for anyone stumbling upon this issue. It does require a few things however:

  1. Use the Nuxt Router Module
  2. Disable auto tracking:
      autoTracking: {
        pageviewOnLoad: false,
        page: false,
      },
  3. Add meta to all page components, and only the page components
  4. Add a mixin in the router.js file (Maybe there's a better place to put this?)
    Vue.mixin({
    mounted() {
    if (this.$metaInfo) {
      this.$ga.page({
        page: this.$router.currentRoute.path,
        title: this.$metaInfo.title,
        location: window.location.href,
      });
    }
    },
    });

I'm now getting the correct url's and titles tracked on all pages.

ricardogobbosouza commented 5 years ago

Just reviewing, this problem still persists

manniL commented 5 years ago

We will improve handling on vue-meta side first.

Jones-S commented 5 years ago

No updates so far, right?

manniL commented 5 years ago

@Jones-S WIP (in https://github.com/nuxt/vue-meta/)

123mitnik commented 5 years ago

same issue integrating inside quasar-framework

heaviss commented 5 years ago

@Jones-S WIP (in https://github.com/nuxt/vue-meta/)

@manniL Any updates here? I couldn't find any issue in vue-meta to subscribe on.

hagemann commented 5 years ago

@heaviss https://github.com/nuxt/vue-meta/issues/259

manniL commented 5 years ago

Closing here as v2 of vue-meta has been released. Please ping if the issue still occurs.

ricardogobbosouza commented 5 years ago

@manniL re-open The last version of nuxt is still v2.8.1 that does not include vue-meta in version v2 https://github.com/nuxt/nuxt.js/blob/v2.8.1/packages/vue-app/package.json#L18

ricardogobbosouza commented 5 years ago

Waiting v2.9.0 to close

MLDMoritz commented 5 years ago

I used these resolutions to force version 2 of the library but the issue still persists.

"resolutions": {
  "vue-meta": "~2.1.1"
}
manniL commented 5 years ago

cc @pimlie

hagemann commented 5 years ago

v2.9.0 is out. The issue persists. Is this module already on vue-meta 2.0 or above?

manniL commented 5 years ago

This module isn't directly related to vue meta. Your project must be using vue-meta > 2.0 (by default on Nuxt v2.9 and above)

hagemann commented 5 years ago

Got it. I had it upgraded to v2.9, but realtime page titles continue to trail by one page. I was under the assumption that the update would resolve the issue.

zerdmann commented 4 years ago

@hagemann Did you ever get anything figured out for this? We are having this problem too. It's especially frustrating after waiting for 2.9, assuming this would be fixed.

hagemann commented 4 years ago

@zerdmann No change whatsoever. Frustrating indeed.

cschweda commented 4 years ago

Is there a fix for this yet? Or any fixes planned?

MatteoGabriele commented 4 years ago

I'm currently using Router.onReady on the vue-gtag package which i think should fix this one. I might try and see

MatteoGabriele commented 4 years ago

@cschweda so just released version 5.20.2 of vue-analytics and I guess the nuxt module will update soon too with PR but you can already use the fix by re-installing your node modules. let me know if u still see the issue. other than this I can't do much more

MatteoGabriele commented 4 years ago

please @cschweda or @manniL or whomever: kindly post if the fix works or not so that we can close this ticket thanks

cschweda commented 4 years ago

Well, I rm -rf'd node_modules and package-lock.json.

Then I did a reinstall: npm i.

Still looks like the page title on Analytics is a step behind the actual page.

In other words, if I load the site and watch the hits on GA in real-time, I see:

Then if I navigate to /x, I still see Home as the page title.

And if I navigate to /y, I then see Page X as the page title.

package.json

"dependencies": {
...
"nuxt": "^2.11.0"
...
},
 "devDependencies": {
...
"@nuxtjs/google-analytics": "^2.2.2",
...
}

nuxt.config.js:

...
buildModules: [
    [
      '@nuxtjs/google-analytics',
      {
        id: 'UA-XXXXXXX-4'
      }
    ]
  ]
...
MatteoGabriele commented 4 years ago

ok then... I'm out! 🤣 that was the only thing I could improve regarding this ticket. is this ticket for Nuxt or for vue-meta? because if it's for vue-meta I would move this out of here because looks like nobody is taking care of it. just saying

thanks

pimlie commented 4 years ago

The title update delay is a known issue with nuxt, vue-meta and transitions. Its caused due to vue-meta/analytics running when navigation has finished but when using transitions (the nuxt default) then the transition has only just started at that time.

Its easiest to set features: { transitions: false } in your nuxt.config if you dont use transitions anyway. Otherwise wait for the transition to finish before pushing analytics. Not sure how to do that reliably though

ricardogobbosouza commented 4 years ago

Hi @MatteoGabriele This needs to come back https://github.com/MatteoGabriele/vue-analytics/commit/cc858f7da658749469ef2e2c093e6d3f966f95f5#diff-4c83e9e52b5cced0fad40de222197a41L109 traceRoute needs to called inside nextTick

Hi @pimlie this has been merged https://github.com/nuxt/vue-meta/issues/475 however a new version was not released

With these two updates and features: {transitions: false} this issue will be resolved.

MatteoGabriele commented 4 years ago

@ricardogobbosouza how come the nextTick is better than the ready hook of vue-router? I'm just curious

thanks for the update

ricardogobbosouza commented 4 years ago

@MatteoGabriele you can keep the hook ready ... but we still need nextTick. I can't tell if it's better or worse, but it's necessary.

MatteoGabriele commented 4 years ago

mmmm not really an exhaustive answer but it was working before so I guess I'll just combine the two and pray the gods 😄

ricardogobbosouza commented 4 years ago

With your update and the next vue-meta release with the features: {transitions: false} option this should be fixed, I hope! :grin:

ricardogobbosouza commented 4 years ago

@cbodin @pimlie @MatteoGabriele

Finally it works, make sure:

Example:

package.json

{
    "dependencies": {
        "nuxt": "^2.11.0"
    },
    "devDependencies": {
        "@nuxtjs/google-analytics": "^2.2.3"
    }
}

nuxt.config.js

export default {
    buildModules: [
        '@nuxtjs/google-analytics'
    ],

    features: {
        transitions: false
    },

    vueMeta: {
        refreshOnceOnNavigation: true
    },

    googleAnalytics: {
        id: 'UA-12301-2',
        debug: {
            enabled: true,
        },
        autoTracking: {
            pageviewTemplate: route => {
                return {
                    page: route.path,
                    title: window.document.title,
                    location: window.location.href,
                };
            }
        }
    }
}

page1.vue

<template>
  <div>
    <h1 class="title">Page 1</h1>

    <div class="links">
      <nuxt-link to="page1">Page 1</nuxt-link>
      <nuxt-link to="page2">Page 2</nuxt-link>
    </div>
  </div>
</template>

<script>
export default {
  head() {
    return {
      title: 'Page 1'
    };
  },
}
</script>

page2.vue

<template>
  <div>
    <h1 class="title">Page 2</h1>

    <div class="links">
      <nuxt-link to="page1">Page 1</nuxt-link>
      <nuxt-link to="page2">Page 2</nuxt-link>
    </div>
  </div>
</template>

<script>
export default {
  head() {
    return {
      title: 'Page 2'
    };
  },
}
</script>
MatteoGabriele commented 4 years ago

nice! good job :) so shall we close it? @ricardogobbosouza

pimlie commented 4 years ago

@ricardogobbosouza How is this working correctly without using vue-meta's afterNavigation?

ricardogobbosouza commented 4 years ago

Hi @pimlie needs to enable vueMeta: { refreshOnceOnNavigation: true }

pimlie commented 4 years ago

Yeah, but that only defines that vueMeta should refresh once. If you want to have the guarantee that document.title has been updated you need to track the page view within vue-meta's afterNavigation hook.

Is it possible to manually track the page view with vue-analytics?

ricardogobbosouza commented 4 years ago

For tracking manually https://github.com/MatteoGabriele/vue-analytics/blob/master/docs/page-tracking.md#manual-page-tracking

pimlie commented 4 years ago

@ricardogobbosouza Thanks for that link. To track analytics more reliably the preferred way to track analytics would then be:

NOTE: afterNavigation isnt called in the context of the page/component that was changed. So if you eg add afterNavigation in your nuxt.config you need to find your own way to have acces to $ga in it. Not sure what the best method is.

    afterNavigation() {
      $ga.page({
        page: '/',
        title: 'Home page',
        location: window.location.href
      })
    }
givp commented 4 years ago

For anyone else who comes across this thread. Adding features: { transitions: false } will fix the GA title issue but it will mess up scrolling positions as you route from page to page. It took me a while to find this but this will make sure your pages are scrolled to the top after every route change: https://nuxtjs.org/api/configuration-router#scrollbehavior

rnakashiro commented 4 years ago

Hi, I had same problem and solved it without features: { transitions: false }.

In nuxt.js repository, I read a comment that the delay is intentional and fits to the transition duration. So, this is not bug, it's nuxt's behavior, I think. https://github.com/nuxt/nuxt.js/issues/6330#issuecomment-525898568

And I read the nuxt.js document about transition hooks. https://nuxtjs.org/api/pages-transition/

Then, I could track with title by using after-enter hook, with code below.

// layouts/default.vue
<template>
  <transition v-on:after-enter="transitionAfterEnter">
    <nuxt />
  </transition>
</template>

<script lang="ts">
@Component({
  ...
})
export default class Default extends Vue {
  ...

  public transitionAfterEnter(): void {
    // Your GTM client class
    GTMClient.shared.gaPageView(this.$route.fullPath)

    // or without class
    window['dataLayer'].push({
      pageType: 'pageView',
      routeName: document.title,
      ...
    })
  }
}
</script>

Also, you can confirm previous screen's title by enter hook, so after-enter hook is suitable for this, I suppose. 😄