GoogleChromeLabs / web-vitals-report

Measure and report on your Web Vitals data in Google Analytics
https://web-vitals-report.web.app
Apache License 2.0
504 stars 48 forks source link

Transferring field attribution to UA #24

Closed voxtermen closed 1 year ago

voxtermen commented 1 year ago

First of all, I want to thank you for an incredibly cool tool!

We are trying to deal with the transfer of attribution of fields to the UA from Google.

Step by step:

1) We have connected the library and added a function:

import {onCLS, onFID, onLCP} from 'https://unpkg.com/web-vitals@3/dist/web-vitals.attribution.js?module';
function sendToGoogleAnalytics({name, delta, value, id, attribution}) {...}

2) and enabled field attribution:

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'FID':
      eventParams.debug_target = attribution.eventTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
  }
    case 'FID':
      eventParams.debug_target = attribution.eventTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
  }

3) Passing the results to GA

onCLS(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);

But we do not get the result in the form of fields (div and so on) that led to the greatest changes in CLS, FND, LCP.

Tell me, please, what else do we need to do?

tunetheweb commented 1 year ago

Can you show what you are doing with your eventParams?

This needs to be sent to GA like this in GA4:

gtag('event', name, eventParams);

Or with a custom dimension in prior versions of GA:

        ga('send', 'event', {
          eventCategory: 'Web Vitals',
          eventAction: name,
          // The `id` value will be unique to the current page load. When sending
          // multiple values from the same page (e.g. for CLS), Google Analytics can
          // compute a total by grouping on this ID (note: requires `eventLabel` to
          // be a dimension in your report).
          eventLabel: id,
          // Google Analytics metrics must be integers, so the value is rounded.
          // For CLS the value is first multiplied by 1000 for greater precision
          // (note: increase the multiplier for greater precision if needed).
          eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
          // Use a non-interaction event to avoid affecting bounce rate.
          nonInteraction: true,
          // Use `sendBeacon()` if the browser supports it.
          transport: 'beacon',

          // OPTIONAL: any additional params or debug info here.
          // See: https://web.dev/debug-web-vitals-in-the-field/
          // dimension1: '...',
          // dimension2: '...',
          dimension1: eventParams.debug_target
          // ...
        });
voxtermen commented 1 year ago

Thanks for the answer! This is how our code looks completely


<script type="module">
  import {onCLS, onFID, onLCP} from 'https://unpkg.com/web-vitals@3/dist/web-vitals.attribution.js?module';

function sendToGoogleAnalytics({name, delta, value, id, attribution}) {
  const eventParams = {
    // Built-in params:
    value: delta, // Use `delta` so the value can be summed.
    // Custom params:
    metric_id: id, // Needed to aggregate events.
    metric_value: value, // Optional.
    metric_delta: delta, // Optional.
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'FID':
      eventParams.debug_target = attribution.eventTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
</script>
voxtermen commented 1 year ago

Do I need to add something to the script or do something on the GA side?

tunetheweb commented 1 year ago

I'd just set it up in the exact same way and am seeing debug_target event parameters on the LCP events.

Here's is a view from the Real Time screen in GA:

image

Are you seeing the LCP events in GA4 but just not the debug_target? Or are you not seeing the events at all?

Can you see the data being sent in the Network panel? Here's an example from my test site:

image

You can see for yourself here: https://www.tunetheweb.com/experiments/ga4/

voxtermen commented 1 year ago

Thanks a lot! I think I'm beginning to understand. All necessary data is transmitted: image

This means that all the necessary data is being transmitted. But I can't figure out how to customize their representation, as in the screenshot below.

image Tell me, please, do I need to add something to the script code?

tunetheweb commented 1 year ago

Ah, sorry, I missed that this issue was in the Web Vitals Report repo, and not the web vitals library - apologies.

As noted in the README unfortunately the Web Vitals Report is not compatible with GA4 so this cannot be used.

@philipwalton detailed how to extract this information from GA4 via BigQuery in this article: https://web.dev/vitals-ga4/, including this section on extracting the Debug information: https://web.dev/vitals-ga4/#example-queries-2.

Let us know how that looks, and then think we can close out this issue as GA4 support is being tracked in #22 ?

voxtermen commented 1 year ago

Oh, thank you!

Do I understand correctly that if I use gtag or an old version of GA, then the script (https://github.com/GoogleChromeLabs/web-vitals-report/issues/24#issuecomment-1315291714 ) will transmit data in the form as in the picture:

image

Or does the script only work with the GA4 version?

tunetheweb commented 1 year ago

You need to set up a custom dimension in Google Analytics, and then send the data to that custom dimension with the script as detailed in my initial comment. For example if you set up Custom Dimension 1 in GA then you send eventParams.debug_target to that like below:

        ga('send', 'event', {
          eventCategory: 'Web Vitals',
          eventAction: name,
          eventLabel: id,
          eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
          nonInteraction: true,
          transport: 'beacon',
          dimension1: eventParams.debug_target
          // ...
        });

You then tell Web Vitals Report the dimension number in the Debug Dimension field:

image
voxtermen commented 1 year ago

Thanks!

It turns out that the script code will be like this:

<script type="module">
import {onCLS, onFID, onLCP} from 'https://unpkg.com/web-vitals@3/dist/web-vitals.js?module';

function sendToGoogleAnalytics({name, delta, id}) {
  ga('send', 'event', {
          eventCategory: 'Web Vitals',
          eventAction: name,
          eventLabel: id,
          eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
          nonInteraction: true,
          transport: 'beacon',
          dimension1: eventParams.debug_target
        });
}

onCLS(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
</script>

Next I need to create custom dimensions in Google UA. And there are difficulties with this. If I understood correctly, then you need to create like this:

image

But this throws an error in the console: image

I'm sure I'm doing something wrong, but I can't find the instructions for it. Could you tell me the next step?

tunetheweb commented 1 year ago

Your code needs to be like this:

function sendToGoogleAnalytics({name, delta, id, attribution}) {

  let debug_target;

  switch (name) {
    case 'CLS':
     debug_target = attribution.largestShiftTarget;
      break;
    case 'FID':
     debug_target = attribution.eventTarget;
      break;
    case 'LCP':
     debug_target = attribution.element;
      break;
  }

  ga('send', 'event', {
          eventCategory: 'Web Vitals',
          eventAction: name,
          eventLabel: id,
          eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
          nonInteraction: true,
          transport: 'beacon',
          dimension1: debug_target
        });
}

onCLS(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
</script>
voxtermen commented 1 year ago

Many thanks to you, Barry! It works!

voxtermen commented 1 year ago

Hello! Thank you again for the unique and cool tool! Another question arose. The code above works for Google UA. But Google UA connects mainly via gtag. Like this:

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXX-X"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'UA-XXX-X');
</script>

Hence ga() will not send data to Google UA. So I need to use the Core Web Vitals script for UA gtag. like this:


<script type="module">
import {onCLS, onFID, onLCP} from 'https://unpkg.com/web-vitals@3/dist/web-vitals.attribution.js?module';
function sendToGoogleAnalytics({name, delta, id, attribution}) {
 let debug_target;

  switch (name) {
    case 'CLS':
     debug_target = attribution.largestShiftTarget;
      break;
    case 'FID':
     debug_target = attribution.eventTarget;
      break;
    case 'LCP':
     debug_target = attribution.element;
      break;
  }

  gtag('event', name, {
    event_category: 'Web Vitals',
    event_label: id,
    value: Math.round(name === 'CLS' ? delta * 1000 : delta),
    non_interaction: true,
    dimension1: debug_target  });
}

onCLS(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
</script>

Please tell me what to enter here in this case? image

Or in the case of gtag UA, we can't get data in the fields like here?

image

tunetheweb commented 1 year ago

gtag() is just a wrapper around the standard ga() calls.

So you can use the same values. the ga in those fields refers to "Google Analytics" rather than the ga() function used to send data from the page to Google Analytics.

voxtermen commented 1 year ago

Thanks! I get an error after changing ga to gtag and try to use dimension5.

image

dimension5:

image

Code:

<script type="module">
import {onCLS, onFID, onLCP} from 'https://unpkg.com/web-vitals@3/dist/web-vitals.attribution.js?module';
function sendToGoogleAnalytics({name, delta, id, attribution}) {
 let debug_target;

  switch (name) {
    case 'CLS':
     debug_target = attribution.largestShiftTarget;
      break;
    case 'FID':
     debug_target = attribution.eventTarget;
      break;
    case 'LCP':
     debug_target = attribution.element;
      break;
  }

  gtag('event', name, {
    event_category: 'Web Vitals',
    event_label: id,
    value: Math.round(name === 'CLS' ? delta * 1000 : delta),
    non_interaction: true,
    dimension5: debug_target  });
}

onCLS(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
</script>
tunetheweb commented 1 year ago

Are you sure this is not a GA4 instance of Google Analytics? Can you see the data in the Google Analytics? Can you see the data being sent in Dev Tools?

voxtermen commented 1 year ago

Are you sure this is not a GA4 instance of Google Analytics? Yes, I created a separate tag and indicated that I would use Google UA.

Can you see the data in the Google Analytics? Yes, the data is coming image

Oops, sorry! The data started coming in, maybe it needed a little time. image

A small point is that the data is not specified for individual pages. Does it also take time and wait a little? image

tunetheweb commented 1 year ago

I would have thought that should have landed at the same time as the attribution debug information but it can take some time so I'd try again later today.

voxtermen commented 1 year ago

Once again and many many many times, thank you very much, Barry!