Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A4A: Setup Google Analytics. #90805

Open
wants to merge 6 commits into
base: trunk
Choose a base branch
from
Open

Conversation

jkguidaven
Copy link
Contributor

@jkguidaven jkguidaven commented May 16, 2024

This PR updates the Google Analytics package to recognize the A4A environment and use the correct Gtag ID. The main goal is for the initial setup. We can track page views.

Proposed Changes

  • Add A4A GTag constant and update Google analytics setup function to recognize A4A environment.

Why are these changes being made?

  • Google Analytics provides an easy way to track users' journeys and measure user engagement at a high-level visuals. This PR setups GA to work with A4A using A4A-specific properties (Gtag IDs).

Testing Instructions

Pre-merge Checklist

  • Has the general commit checklist been followed? (PCYsg-hS-p2)
  • https://wpcalypso.wordpress.com/devdocs/docs/testing/index.md for your changes?
  • Have you tested the feature in Simple (P9HQHe-k8-p2), Atomic (P9HQHe-jW-p2), and self-hosted Jetpack sites (PCYsg-g6b-p2)?
  • Have you checked for TypeScript, React or other console errors?
  • Have you used memoizing on expensive computations? More info in Memoizing with create-selector and Using memoizing selectors and Our Approach to Data
  • Have we added the "[Status] String Freeze" label as soon as any new strings were ready for translation (p4TIVU-5Jq-p2)?
  • For changes affecting Jetpack: Have we added the "[Status] Needs Privacy Updates" label if this pull request changes what data or activity we track or use (p4TIVU-aUh-p2)?

@jkguidaven jkguidaven self-assigned this May 16, 2024
) => {
if ( isJetpackEnv ) {
return TRACKING_IDS.jetpackGoogleAnalyticsGtag;
} else if ( isAkismetEnv ) {
return TRACKING_IDS.akismetGoogleAnalyticsGtag;
} else if ( isA4AEnv ) {
return TRACKING_IDS.a4aGoogleGA4GTag;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need a separate tracking ID here? It seems that Jetpack and Akismet are using different tags. I'm not sure whats the difference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the tracking IDs is for Google Analytics previous to GA4. One of them starts with UA- and GA4 codes start with G- the one that you have. I am not sure if we absolutely need to have both, I'll defer to @robertsreberski on that

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't need both, I'd say we should remove A4A from this getGaGtag function

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all UA (Universal Analytics). It's a bit confusing because the Gtag is used across Google Products, e.g., Google Ads, Tag Manager (I think), and the old Universal Analytics.

UA does not process data anymore, and it's deprecated/read-only. These will be cleaned up, so there should be no reason to add the tag here. You can see in analytics/ad-tracking/google-analytics.js this is called in setupGoogleAnalyticsGtag, but prior to that the other Gtag setup for GA4 is called (GA4.setup( params )).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this one is good finding 😅 It's indeed obsolete, unused code. We can write down a follow-up clean up maintenance task for that.

@@ -41,7 +41,8 @@ export function fireGoogleAnalyticsPageView(
urlPath,
pageTitle,
useJetpackGoogleAnalytics = false,
useAkismetGoogleAnalytics = false
useAkismetGoogleAnalytics = false,
useA4AGoogleAnalytics = false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I be changing fireGoogleAnalyticsPageView function for us to track page view?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I believe that is correct

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's needed 👍

@matticbot
Copy link
Contributor

matticbot commented May 16, 2024

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

App Entrypoints (~258 bytes added 📈 [gzipped])

name                   parsed_size           gzip_size
entry-subscriptions         +623 B  (+0.0%)     +164 B  (+0.0%)
entry-stepper               +444 B  (+0.0%)      +73 B  (+0.0%)
entry-main                  +444 B  (+0.0%)      +73 B  (+0.0%)
entry-login                 +325 B  (+0.0%)      +85 B  (+0.0%)
entry-domains-landing        -41 B  (-0.0%)      -21 B  (-0.0%)
entry-browsehappy            -41 B  (-0.0%)      -21 B  (-0.0%)

Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.

Sections (~11165 bytes removed 📉 [gzipped])

name                                parsed_size           gzip_size
a8c-for-agencies-signup                  +554 B  (+0.7%)     +655 B  (+2.3%)
a8c-for-agencies-settings                +554 B  (+0.3%)     +451 B  (+0.8%)
a8c-for-agencies-partner-directory       +554 B  (+0.3%)     +421 B  (+0.8%)
a8c-for-agencies-sites                   +412 B  (+0.0%)      +66 B  (+0.0%)
a8c-for-agencies-purchases               +399 B  (+0.1%)      +62 B  (+0.0%)
a8c-for-agencies-referrals               +358 B  (+0.1%)      +59 B  (+0.0%)
a8c-for-agencies-overview                +358 B  (+0.2%)      +20 B  (+0.0%)
a8c-for-agencies-migrations              +358 B  (+0.2%)      -64 B  (-0.1%)
a8c-for-agencies-marketplace             +358 B  (+0.1%)      +34 B  (+0.0%)

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

Legend

What is parsed and gzip size?

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

@matticbot
Copy link
Contributor

matticbot commented May 16, 2024

This PR modifies the release build for the following Calypso Apps:

For info about this notification, see here: PCYsg-OT6-p2

  • blaze-dashboard
  • editing-toolkit
  • odyssey-stats

To test WordPress.com changes, run install-plugin.sh $pluginSlug add/a4a/google-analytics on your sandbox.

@jkguidaven jkguidaven requested a review from a team May 20, 2024 15:44
@matticbot matticbot added the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label May 20, 2024
@jkguidaven
Copy link
Contributor Author

I am Adding Martech as a reviewer to double-check that I am changing the right files and covering everything needed for the initial setup.

@jkguidaven jkguidaven marked this pull request as ready for review May 20, 2024 15:54
@jkguidaven jkguidaven changed the title A4A: Setup Google analytics. A4A: Setup Google Analytics. May 20, 2024
@elliottprogrammer
Copy link
Contributor

I am Adding Martech as a reviewer to double-check that I am changing the right files and covering everything needed for the initial setup.

Hmm, I tried functional testing per the testing instructions above, however I am not seeing any googletagmanager tracking requests... 🤔
@robertsreberski, would you mind giving this PR a look/review?

@jkguidaven
Copy link
Contributor Author

@elliottprogrammer, Thank you for looking into this. You may need to sign up for an Agency account. I'll add it in the test instructions.

https://agencies.automattic.com/signup

Copy link
Contributor

@CodeyGuyDylan CodeyGuyDylan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the scope of this PR is, but to actually track the page views, I believe you have to use the PageViewTracker component defined here

Example usage:

<PageViewTracker
options={ { useJetpackGoogleAnalytics: true } }
path="/checkout/jetpack/thank-you/:site/:product"
properties={ { product_slug: productSlug } }
title="Checkout > Jetpack Thank You"
/>

Copy link
Contributor

@gmovr gmovr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments. :)

The setup here looks good in terms of tracking IDs, environment setup, etc. I tested by signing up for an A4A account, and I can see the Gtag being initialized.

Local testing

I tested building it locally with yarn start-a8c-for-agencies, where I changed the development.json config to allow ad-tracking (to avoid the URL flags). Note: I also need to add the cookie-banner as I'm in the GDPR zone, and the trackers won't fire unless the consent is accepted.

diff --git a/config/a8c-for-agencies-development.json b/config/a8c-for-agencies-development.json
index 351c2c67fc..d7cff47031 100644
--- a/config/a8c-for-agencies-development.json
+++ b/config/a8c-for-agencies-development.json
@@ -28,7 +28,8 @@
        ],
        "oauth_client_id": 95928,
        "features": {
-               "ad-tracking": false,
+               "ad-tracking": true,
+               "cookie-banner": true,
                "a8c-for-agencies": true,
                "a8c-for-agencies/wpcom-creator-plan-purchase-flow": true,
                "a8c-for-agencies/import-site-from-wpcom": true,

I also tested removing the ID in getGaGtag, and it works as expected (as this is old UA code).

Page views

Screenshot 2024-05-24 at 11 06 18

I see recordPageView is called from calypso/lib/analytics/page-view. So, that should already be handled. Example in ./sections/overview/controller.tsx.

Note: I think the default behavior in GA4 is to automatically trigger page views as well.

It tries to guess when that happens in a SPA, but it's not as predictable as firing these off ourselves. It gives us "dirty" page views, e.g. where data is not "normalized.", making it harder to see page views for a given route since the route may contain a unique parameter.

One example is http://agencies.localhost:3000/purchases/invoices. I don't have any invoices, but I imagine the URLs like http://agencies.localhost:3000/purchases/invoices/12341234, where we'd track the individual invoice slug, like http://agencies.localhost:3000/purchases/invoices/<id>, instead of having many slugs with 1-2 views each (per invoice ID).

Turning off history tracking and using the page view functionality may clean up page views and prevent duplicates. Also, Google Analytics has limits on how many unique slugs it can keep track of -- so you'd get a lot of data sampling.

I checked the property, and the history-based page view detection is active (while on WPcom it's turned off). I can turn it off, or we can ship and check the data (probably the best option).

Screenshot 2024-05-24 at 10 45 56

@@ -64,7 +68,7 @@ export function fireGoogleAnalyticsPageView(

window.gtag(
'config',
getGaGtag( useJetpackGoogleAnalytics, useAkismetGoogleAnalytics ),
getGaGtag( useJetpackGoogleAnalytics, useAkismetGoogleAnalytics, useA4AGoogleAnalytics ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just leaving a note here, but I wonder if we should change this structure at some point. It seems a bit messy to pass in arguments like this. Initially, it was just for Jetpack, but it gets a bit out of hand as we keep adding sites. It's not a blocker for this, though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've documented the possible improvement on our maintenance board - as it relates in a large chunk to Jetpack/Akismet use cases.

@@ -41,7 +41,8 @@ export function fireGoogleAnalyticsPageView(
urlPath,
pageTitle,
useJetpackGoogleAnalytics = false,
useAkismetGoogleAnalytics = false
useAkismetGoogleAnalytics = false,
useA4AGoogleAnalytics = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's needed 👍

) => {
if ( isJetpackEnv ) {
return TRACKING_IDS.jetpackGoogleAnalyticsGtag;
} else if ( isAkismetEnv ) {
return TRACKING_IDS.akismetGoogleAnalyticsGtag;
} else if ( isA4AEnv ) {
return TRACKING_IDS.a4aGoogleGA4GTag;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all UA (Universal Analytics). It's a bit confusing because the Gtag is used across Google Products, e.g., Google Ads, Tag Manager (I think), and the old Universal Analytics.

UA does not process data anymore, and it's deprecated/read-only. These will be cleaned up, so there should be no reason to add the tag here. You can see in analytics/ad-tracking/google-analytics.js this is called in setupGoogleAnalyticsGtag, but prior to that the other Gtag setup for GA4 is called (GA4.setup( params )).

Copy link
Contributor

@robertsreberski robertsreberski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some additional comments, but the implementation looks largely good.

) => {
if ( isJetpackEnv ) {
return TRACKING_IDS.jetpackGoogleAnalyticsGtag;
} else if ( isAkismetEnv ) {
return TRACKING_IDS.akismetGoogleAnalyticsGtag;
} else if ( isA4AEnv ) {
return TRACKING_IDS.a4aGoogleGA4GTag;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this one is good finding 😅 It's indeed obsolete, unused code. We can write down a follow-up clean up maintenance task for that.

@@ -64,7 +68,7 @@ export function fireGoogleAnalyticsPageView(

window.gtag(
'config',
getGaGtag( useJetpackGoogleAnalytics, useAkismetGoogleAnalytics ),
getGaGtag( useJetpackGoogleAnalytics, useAkismetGoogleAnalytics, useA4AGoogleAnalytics ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've documented the possible improvement on our maintenance board - as it relates in a large chunk to Jetpack/Akismet use cases.

@jkguidaven
Copy link
Contributor Author

Thanks everyone for the great feedback. I truly appreciate it. I apologize for the delay in responding to the PR. I had some other stuff to prioritize.

I've made some adjustments to address the comments made. 🙏

Copy link
Contributor

@robertsreberski robertsreberski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on the changes, the code looks good!

One functional change, I've realized by debugging (btw, I recommend Analytics Debugger Chrome extension) that we just track page view event for WPCOM tracker on /overview page.

The implementation of page view changes look good, but we need to extend the usage of to make use of them (i.e. here: https://github.com/Automattic/wp-calypso/blob/trunk/client/a8c-for-agencies/sections/overview/controller.tsx).

It should be something like this:

<PageViewTracker
    title="Overview"
    path={ context.path }
    options={ { useA8CForAgenciesGoogleAnalytics: true } }
/>

So to leverage the changes from client/lib/analytics/page-view.js.

@jkguidaven
Copy link
Contributor Author

It should be something like this:

<PageViewTracker
    title="Overview"
    path={ context.path }
    options={ { useA8CForAgenciesGoogleAnalytics: true } }
/>

So to leverage the changes from client/lib/analytics/page-view.js.

Thanks. I've made the necessary changes so all pages pass the correct options.

28d4ca1

Copy link
Contributor

@robertsreberski robertsreberski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works well for me, I receive the page view for the correct tag id on /overview!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A8c Agencies [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants