MatteoGabriele / vue-gtag

Global Site Tag plugin for Vue (gtag.js)
https://matteo-gabriele.gitbook.io/vue-gtag/
MIT License
866 stars 67 forks source link

Track landing page view before router redirect #405

Open ipa1981 opened 2 years ago

ipa1981 commented 2 years ago

In our app we have router redirect to sign in page if user's auth token has expired. If we want additionally track UTM parameters (utm_source, utm_medium, etc), we pass it in the URL. For example:

/dashboard?utm_source=push&utm_medium=welcome

If a user is signed in, the VueGtag takes this URL with utm_* params and tracks them correctly. If a user is not signed in and we redirect it immediately to /sign-up, and it tracks the latter URL. Probably to the race condition.

Of course possible solutions are:

If there any recommendation how to handle such race conditions in a best way or do we miss something?

sneko commented 2 years ago

Hi @ipa1981 ,

Did you find a solution? I'm in almost the same case:

I think that's possible by catching the original URL before the router is ready and running. You could get UTM parameters, then we should push them manually to Google Analytics (maybe through a specific set()...), and then we could remove them from the current route (either by stripping them before the router acts, or by using a router.replace({ query: allCurrentParamsWithoutUTMOnes }).

The hard part for now is how to explicitly pass them to gtag.js... need to have a look.

Any thought @MatteoGabriele ?

ipa1981 commented 2 years ago

@sneko nope. We didn't find a solution, nor anyone gave any suggestions here as you may notice. So still live with some visits get untracked :)

sneko commented 2 years ago

@ipa1981 in case you still want to solve this issue I worked on a third-party library (https://github.com/sneko/utm-synapse) that I integrated into vue-gtag. Please see https://github.com/MatteoGabriele/vue-gtag/pull/445 for details 👍

PS: about your wondering on onAfterTrack(), this one is not called for the first track, just for subsequent ones (see https://github.com/MatteoGabriele/vue-gtag/blob/8c2e39555fb867a38251ca48c6011256603df69d/src/add-routes-tracker.js#L18-L47).

ipa1981 commented 2 years ago

@sneko sounds as a possible solution. Let's then see if @MatteoGabriele could accept this PR.

MatteoGabriele commented 2 years ago

I'm sorry for texting you back so late. I checked the PR that @sneko opened but adding multiple dependencies to handle the UTM tag only seems too much for me. I will try to learn more about it and check how to proceed.

sneko commented 2 years ago

There are 2 dependencies added, they are really lightweight:

  1. mine that have a few methods to manage UTM params
  2. one to fallback if sessionStorage does not exist

I could have for sure implemented methods directly in your library for (1), but it's not scoped to Vue, nor gtag. And for the (2), I could have tried to reinvent the wheel to fallback this, but for me using tested and working librairies is fine too. But I do understand your point it can be a nightmare when having XXXX deps.

To be honest, at first I wanted to not fork your repo just by using the middlewares, so the user could use in addition my library to manage UTM params. But:

But if you find how to arrange this to make it the way the library is, there is no problem for me 😄

HugoMuller commented 2 years ago

Hi,

@MatteoGabriele is there any reason why the hooks onBeforeTrack() and onAfterTrack()are not called on the landing page (first track)? They could be called at least with the current route, like track.

ericuldall commented 1 year ago

big +1 to figuring this out. GA is pretty much useless without the ability to identify where your traffic is coming from.

ericuldall commented 1 year ago

Would the following documentation:

gtag('set', 'campaign', {
  'id': 'abc.123',
  'source': 'google',
  'medium': 'cpc',
  'name': 'spring_sale',
  'term': 'running+shoes',
  'content': 'logolink'
});

Be implemented in api/pageview as:

event('set', 'campaign', {})

Is that correct?

If so could be pretty simply passed through from track.js

const { query } = to;
  let utm = {};
  for (let key in query) {
      if (key.match(/^utm\_/)) {
          utm[key.split('_')[1].replace('campaign', 'id')] = query[key];
      }
  }

  if (Object.keys(utm).length) {
    // we have utm params, let's save them in local storage
    localStorage.setItem('vue_gtag_utm', JSON.stringify(utm));
  } else {
    // we don't have utm params, let's check local storage
    utm = JSON.parse(localStorage.getItem('vue_gtag_utm') || '{}');
  }

  api.pageview(template, utm);

I'm testing this on my end, but want to make sure the event is what I think it is.

UPDATE Seems to work well it's adding the utm params to the page_view request

image
ericuldall commented 1 year ago

Sent a PR, any feedback is appreciated: https://github.com/MatteoGabriele/vue-gtag/pull/517