johannschopplich / nuxt-gtag

🔸 Google Analytics & Ads integration made easy
https://developers.google.com/tag-platform/gtagjs
MIT License
289 stars 8 forks source link

Persist consent state in session #51

Open agracia-foticos opened 4 months ago

agracia-foticos commented 4 months ago

Environment

Reproduction

First consent mode default image

Cookie banner acept partial consent image

But when we navigate, there is a toxic consent that we havent triggered!! image

There is a bug in the module??? Module throws this event???

Describe the bug

First consent mode default image

Cookie banner acept partial consent image

But when we navigate, there is a toxic consent that we havent triggered!! image

There is a bug in the module??? Module throws this event???

Additional context

No response

Logs

No response

agracia-foticos commented 4 months ago

initCommands only must be triggered one time!!! maybe initCommands are triggered in each request... its incorrect, consent mode default only must be setted one time (until user remove/expired cookies)

agracia-foticos commented 4 months ago

With this config

gtag: { id:"XXXXXXX", enabled: true, initCommands: [ // Setup up consent mode ['consent', 'default', { ad_user_data: 'denied', ad_personalization: 'denied', ad_storage: 'denied', analytics_storage: 'denied', wait_for_update: 500, }] ], tags : ["XXXXXXX"] },

the initCommands are triggered in each request, the initCommands only must me triggered only time in session... not only one in each request

johannschopplich commented 4 months ago

Indeed, initCommands should be triggered only once. Can you please provide a minimal reproducible example? Thanks in advance. 🙏

agracia-foticos commented 4 months ago

https://stackblitz.com/edit/nuxt-starter-doubb6

put your ids in nuxt.config.ts gtag section

and press acept or denied and goes to another page... a default consent event is triggered

johannschopplich commented 4 months ago

I don't understand what you mean with "another page". Since there is only app.vue, the Vue Router is not bundled to Nuxt so each redirect will reload the whole page.

When I accept and then deny the consent, the dataLayer contains the ordered events:

grafik

Can you please elaborate what your expected behavior is?

agracia-foticos commented 4 months ago

Sin nombre

I'm using Analytics Debugger chrome extension

In first url, the last action is acept consent mode, and we triger consent with granted. But in second url, you can see that consent default are other time triggered!!

The event #5 in second url is a HACK that we are trying

agracia-foticos commented 4 months ago

I don't understand what you mean with "another page". Since there is only app.vue, the Vue Router is not bundled to Nuxt so each redirect will reload the whole page.

When I accept and then deny the consent, the dataLayer contains the ordered events:

grafik

Can you please elaborate what your expected behavior is?

When i say go to another page, we referer navigate another page without Nuxt link, with a href mode

agracia-foticos commented 4 months ago

this is my window.dataLayer when i navigate to another page through a href link image

consent default its triggered another time, only must be triggered when consent mode isnt setted

agracia-foticos commented 4 months ago

If i remove initCommands: [ // Setup up consent mode ['consent', 'default', { ad_user_data: 'denied', ad_personalization: 'denied', ad_storage: 'denied', analytics_storage: 'denied', wait_for_update: 500, }] ],

Toxic consent default event dissapears!!! init commands only must be triggered until consent mode is pending... if consent mode its updated, initCommands musnt be triggered

johannschopplich commented 4 months ago

The module follows the consent mode specs:

// Define dataLayer and the gtag function.
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

// Set default consent to 'denied' as a placeholder
// Determine actual values based on your own requirements
gtag('consent', 'default', {
  'ad_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied',
  'analytics_storage': 'denied'
});

For the plain Google example, a Redirect from <a>-tag (instead of NuxtLink would lead to the same result: A page refresh will reset the consent.

How are you using Nuxt that you require a hard refresh?

Feel free to open a PR to support state persistance, say in sessionStorage. 🙌

agracia-foticos commented 4 months ago

The module follows the consent mode specs:

// Define dataLayer and the gtag function.
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

// Set default consent to 'denied' as a placeholder
// Determine actual values based on your own requirements
gtag('consent', 'default', {
  'ad_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied',
  'analytics_storage': 'denied'
});

For the plain Google example, a Redirect from <a>-tag (instead of NuxtLink would lead to the same result: A page refresh will reset the consent.

How are you using Nuxt that you require a hard refresh?

Feel free to open a PR to support state persistance, say in sessionStorage. 🙌

gtag('consent', 'default', { 'ad_storage': 'denied', 'ad_user_data': 'denied', 'ad_personalization': 'denied', 'analytics_storage': 'denied' }); This code only must be triggered if user doenst accept or decline consent mode.

Now, we use Nuxt in "non mode spa mode"

the persistance state must be a cookie, not its for a session... maybe you can define expires in a ttl nuxt.config.ts property

johannschopplich commented 4 months ago

Thanks for all the screenshots!

This code only must be triggered if user doenst accept or decline consent mode.

That doesn't seem the case. To state the Gtag docs:

[!NOTE] To adjust the default measurement capabilities, call the gtag('consent', 'default', ...) command on every page of your site before any commands that send measurement data (such as config or event).

agracia-foticos commented 4 months ago

Thanks for all the screenshots!

This code only must be triggered if user doenst accept or decline consent mode.

That doesn't seem the case. To state the Gtag docs:

Note

To adjust the default measurement capabilities, call the gtag('consent', 'default', ...) command on every page of your site before any commands that send measurement data (such as config or event).

Our google account manager tell us that isn't necessary... but we confirm with him this behaviour

agracia-foticos commented 4 months ago

Thanks for all the screenshots!

This code only must be triggered if user doenst accept or decline consent mode.

That doesn't seem the case. To state the Gtag docs:

Note

To adjust the default measurement capabilities, call the gtag('consent', 'default', ...) command on every page of your site before any commands that send measurement data (such as config or event).

In any case, if it is issued, the selected option should be issued, not the consent mode default

agracia-foticos commented 4 months ago

@johannschopplich We are having conversion problems using the initCommands functionality. Please, would it be possible to issue only the initCommands if a "consent updated" has not been issued?

Or maybe create a new functionality like the useTrackEvent that is useConsentUpdated and if used, save the saved options and instead of emitting a default denied on each page, emit the option that was last used

johannschopplich commented 4 months ago

@agracia-foticos I'm sorry, but I don't follow. The initCommands is only ran once. Do you use static generation with Nuxt?

Do you run the consent update before the initCommands?

agracia-foticos commented 4 months ago

@agracia-foticos I'm sorry, but I don't follow. The initCommands is only ran once. Do you use static generation with Nuxt?

Do you run the consent update before the initCommands?

We are Nuxt without SPA mode, therefore every time we load a page, we are issuing a default denied and later an updated granted, which is driving the algorithm crazy. Hence the need for initCommands to only run if consent has not been updated in some way.