vue-gtag icon indicating copy to clipboard operation
vue-gtag copied to clipboard

Warning: New Google Analytics 4 properties break the expected behavior of this plugin and cause double page views.

Open miketromba opened this issue 3 years ago • 19 comments

Description

First of all, thank you for all your hard work on this plugin Matteo! I really appreciate it.

When creating new Google Analytics properties, they now default to Google Analytics version 4 (GA4). The problem is: the default behavior of GA4 properties is incompatible with this plugin right now, and causes unwanted and unexpected behavior.

I spent a lot of time this morning pulling my hair out trying to understand why random page view events were being sent even without auto-tracking enabled... I learned that it is caused by the default behavior of new GA4 properties.

By default, when gtag.js is installed, GA4 properties automatically send page view events on page loads and even page changes based on browser history events, as shown with this data stream setting:

image

This totally clashes with the behavior of this plugin, causing there to be lots of double page views, and is very confusing to those who miss this! (I assume many developers will fall into this trap)

Suggestion

I do not have a specific suggestion right now on how to make this library GA4-compatable, but I highly recommend temporarily updating the documentation in the meantime to include a big warning that the plugin is not ready for GA4 and will cause duplicate page views.

I think this will save developers a lot of time!

miketromba avatar Jan 31 '22 18:01 miketromba

Any news?

antonreshetov avatar Feb 09 '22 09:02 antonreshetov

Bump.. Any update on this bug?

TravisRick avatar Apr 21 '22 11:04 TravisRick

Is v1 of vue-gtag compatible with GA4? I'm still using Vue2 and would like to use this with the new Google Analytics 4.

bruno-71 avatar May 16 '22 17:05 bruno-71

Is this still an issue? Is vue-gtag compatible with Google Analytics 4?

pandalion avatar Jul 08 '22 12:07 pandalion

Thanks, @miketromba, for your feedback, and sorry for responding to you so late. I will try to look into this, but if any of you know a solution already, don't hesitate to drop it here, and maybe we can fix it and fix it sooner.

MatteoGabriele avatar Jul 08 '22 12:07 MatteoGabriele

I am assuming you are using vue-gtag v2

MatteoGabriele avatar Jul 08 '22 12:07 MatteoGabriele

I have based my implementation on google's documentation https://developers.google.com/analytics/devguides/collection/gtagjs/pages there's no specification of being GA4 compatible or not

MatteoGabriele avatar Jul 08 '22 12:07 MatteoGabriele

I might have found the cause on this line. https://github.com/MatteoGabriele/vue-gtag/blob/master/src/api/pageview.js#L38-L40 I have published a beta version of the fix. Can someone have a look to see if this fixes it? [email protected] thanks a lot

MatteoGabriele avatar Jul 08 '22 13:07 MatteoGabriele

@MatteoGabriele would love to test but would need the patch for the legacy version using Vue 2.

jasperf avatar Aug 09 '22 04:08 jasperf

Here's a small plugin that provides basic tracking functions of gtag.js with GA4 properties- without needing any 3rd party libraries. The heavy lifting is done by GA4's default auto-tracking behavior.

It works well on my end, but I suggest you test to make sure it works well in your own project.

Note: if you're not using nuxt, the plugin logic is the same, just adjust the code to work in your vue environment.

Nuxt 3 GA4 plugin plugins/gtag.client.js

Note: make sure to include .client.js at the end which tells Nuxt to only run it on the browser.

const gtagId = "YOUR_GA4_ID"

export default defineNuxtPlugin(() => {
    
    // Create gtag function & define gtag deps (window.dataLayer array)
    window.dataLayer = window.dataLayer || []
    function gtag(){dataLayer.push(arguments)}
    gtag('js', new Date())
    
    // Config with gtagId & send initial page view
    gtag('config', gtagId, { send_page_view: true })
    
    // Inject gtag function
    return { provide: { gtag } }
})

Nuxt 2 GA4 plugin plugins/gtag.client.js

Note: make sure to include .client.js at the end which tells Nuxt to only run it on the browser.

const gtagId = "YOUR_GA4_ID"

export default (_, inject) => {

    // Create gtag function & define gtag deps (window.dataLayer array)
    window.dataLayer = window.dataLayer || []
    function gtag(){dataLayer.push(arguments)}
    gtag('js', new Date())
    
    // Config with gtagId & send initial page view
    gtag('config', gtagId, { send_page_view: true })

    // Inject gtag function
    inject('gtag', gtag)
}

Then make sure to add this script to your nuxt config file... (replace YOUR_GA4_ID in the URL)

nuxt.config.ts (Nuxt 3)

export default defineNuxtConfig({
  //...
  app: {
    head: {
      script: [
        { src: 'https://www.googletagmanager.com/gtag/js?id=YOUR_GA4_ID', async: true }
      ]
    }
  }
})

nuxt.config.js (Nuxt 2)

export default {
  //...
  head: {
    script: [
      { src: 'https://www.googletagmanager.com/gtag/js?id=YOUR_GA4_ID', async: true }
    ]
  }
}

By default, this should auto-track router navigation in your app, but if you want to tap into the other gtag features, use the injected $gtag property.

miketromba avatar Oct 03 '22 21:10 miketromba

Am using the Vue 2 version and it does seem to work with GA4 as well so not having a lot of issues. Thanks for sharing @miketromba . Perhaps @MatteoGabriele can put it to use.

jasperf avatar Oct 03 '22 23:10 jasperf

miketromba for nuxt 3 code dosesn't work at all and has a lot of console warnings related with window object.

stefan-golus avatar Oct 13 '22 09:10 stefan-golus

@nomtek-sgolus That might be because it's trying to run on the server side (if you're using SSR) - I have my file named gtag.client.js - this tells Nuxt 3 to only run it on the browser.

image

miketromba avatar Oct 13 '22 14:10 miketromba

@nomtek-sgolus That might be because it's trying to run on the server side (if you're using SSR) - I have my file named gtag.client.js - this tells Nuxt 3 to only run it on the browser.

image

Got it, and yep - it works now 👍

stefan-golus avatar Oct 17 '22 18:10 stefan-golus

Here's a small plugin that provides basic tracking functions of gtag.js with GA4 properties- without needing any 3rd party libraries. The heavy lifting is done by GA4's default auto-tracking behavior.

It works well on my end, but I suggest you test to make sure it works well in your own project.

Note: if you're not using nuxt, the plugin logic is the same, just adjust the code to work in your vue environment.

Nuxt 3 GA4 plugin plugins/gtag.client.js

Note: make sure to include .client.js at the end which tells Nuxt to only run it on the browser.

const gtagId = "YOUR_GA4_ID"

export default defineNuxtPlugin(() => {
    
    // Create gtag function & define gtag deps (window.dataLayer array)
    window.dataLayer = window.dataLayer || []
    function gtag(){dataLayer.push(arguments)}
    gtag('js', new Date())
    
    // Config with gtagId & send initial page view
    gtag('config', gtagId, { send_page_view: true })
    
    // Inject gtag function
    return { provide: { gtag } }
})

Nuxt 2 GA4 plugin plugins/gtag.client.js

Note: make sure to include .client.js at the end which tells Nuxt to only run it on the browser.

const gtagId = "YOUR_GA4_ID"

export default (_, inject) => {

    // Create gtag function & define gtag deps (window.dataLayer array)
    window.dataLayer = window.dataLayer || []
    function gtag(){dataLayer.push(arguments)}
    gtag('js', new Date())
    
    // Config with gtagId & send initial page view
    gtag('config', gtagId, { send_page_view: true })

    // Inject gtag function
    inject('gtag', gtag)
}

Then make sure to add this script to your nuxt config file... (replace YOUR_GA4_ID in the URL)

nuxt.config.ts (Nuxt 3)

export default defineNuxtConfig({
  //...
  app: {
    head: {
      script: [
        { src: 'https://www.googletagmanager.com/gtag/js?id=YOUR_GA4_ID', async: true }
      ]
    }
  }
})

nuxt.config.js (Nuxt 2)

export default {
  //...
  head: {
    script: [
      { src: 'https://www.googletagmanager.com/gtag/js?id=YOUR_GA4_ID', async: true }
    ]
  }
}

By default, this should auto-track router navigation in your app, but if you want to tap into the other gtag features, use the injected $gtag property.

Does this allow the use of this.$gtag.event to trigger events on certain button clicks? Thanks

notflip avatar Dec 01 '22 14:12 notflip

@notflip The $gtag property is just a normal gtag.js object, so you can see all of the possibilities in Google's official docs:

Gtag.js - https://developers.google.com/tag-platform/gtagjs Gtag event tracking - https://developers.google.com/tag-platform/devguides/events

miketromba avatar Dec 01 '22 15:12 miketromba

I might have found the cause on this line. https://github.com/MatteoGabriele/vue-gtag/blob/master/src/api/pageview.js#L38-L40 I have published a beta version of the fix. Can someone have a look to see if this fixes it? [email protected] thanks a lot

Yes, it's fixed the double pageview issue. Can you add it to the v1 as well, please?

pavlovskyarto avatar Mar 08 '23 21:03 pavlovskyarto

I might have found the cause on this line. https://github.com/MatteoGabriele/vue-gtag/blob/master/src/api/pageview.js#L38-L40 I have published a beta version of the fix. Can someone have a look to see if this fixes it? [email protected] thanks a lot

Yes, it's fixed the double pageview issue. Can you add it to the v1 as well, please?

What code are you using to implement vue-gtag? Thanks! Will test with you

notflip avatar Mar 09 '23 06:03 notflip