From 90e83a4bd2c2023c31628b906bd7bfb99254b2b7 Mon Sep 17 00:00:00 2001 From: James Chan Date: Tue, 25 Oct 2022 11:21:27 +0100 Subject: [PATCH] Address PR comments --- CHANGELOG.md | 2 +- .../analytics-ga4/ga4-ecommerce-tracker.js | 14 +++++----- .../analytics-ga4/ga4-page-views.js | 13 ++++++---- docs/analytics-ga4/ga4-ecommerce-tracker.md | 22 +++++++++++----- .../ga4-ecommerce-tracker.spec.js | 10 ++----- .../analytics-ga4/ga4-page-views.spec.js | 26 ++----------------- 6 files changed, 35 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0676968f54..79ad3be726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ ## Unreleased -* **BREAKING:** Fix referrer bug ([PR #2906](https://github.com/alphagov/finder-frontend/pull/2906)) +* **BREAKING:** Fix referrer bug ([PR #3032](https://github.com/alphagov/govuk_publishing_components/pull/3032)) ## 31.2.0 diff --git a/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js b/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js index 93e187fc05..72cf975e61 100644 --- a/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js +++ b/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js @@ -9,13 +9,13 @@ PIIRemover: new GOVUK.analyticsGa4.PIIRemover(), DEFAULT_LIST_TITLE: 'Site search results', - init: function (dynamicPageViewData) { + init: function (referrer) { if (window.dataLayer) { - /* The dynamicPageViewData object is only passed to the init() function as a result of an AJAX request + /* The referrer parameter is only passed to the init() function as a result of an AJAX request (in live_search.js in the finder-frontend repository). Otherwise it will not be available and this indicates a fresh page load. - This is needed to trigger a fresh pageViewTracker push to the dataLayer on dynamic page updates (line 30) and to prevent multiple - click listeners from being applied (line 42). */ - var isNewPageLoad = !dynamicPageViewData + This is needed to trigger a fresh pageViewTracker push to the dataLayer on dynamic page updates and to prevent multiple + click listeners from being applied on this.searchResultsBlocks elements. */ + var isNewPageLoad = !referrer /* The data-ga4-ecommerce attribute may be present on several DOM elements e.g. search results and spelling suggestions, hence why document.querySelectorAll is required */ @@ -28,11 +28,11 @@ /* If the results are updated by JS, the URL of the page will change and this needs to be visible to PA's, hence the pageView object push to the dataLayer. We do not need to send a pageView object on page load as this is handled elsewhere. */ - if (dynamicPageViewData) { + if (referrer) { var pageViewTracker = window.GOVUK.analyticsGa4.analyticsModules.PageViewTracker if (pageViewTracker) { - pageViewTracker.init(dynamicPageViewData) + pageViewTracker.init(referrer) } } diff --git a/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js b/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js index 549bd47ca5..f312daf566 100644 --- a/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js +++ b/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js @@ -9,15 +9,15 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics PIIRemover: new window.GOVUK.analyticsGa4.PIIRemover(), // imported in analytics-ga4.js nullValue: undefined, - init: function (dynamicPageViewData) { - dynamicPageViewData = dynamicPageViewData || {} - + init: function (referrer) { if (window.dataLayer) { var data = { event: 'page_view', page_view: { location: this.getLocation(), - referrer: dynamicPageViewData.referrer || this.getReferrer(), + /* If the init() function receives a referrer parameter, this indicates that it has been called as a part of an AJAX request and + this.getReferrer() will not return the correct value. Therefore we need to rely on the referrer parameter. */ + referrer: referrer || this.getReferrer(), title: this.getTitle(), status_code: this.getStatusCode(), @@ -46,7 +46,10 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics organisations: this.getMetaContent('analytics:organisations'), world_locations: this.getMetaContent('analytics:world-locations'), - dynamic: dynamicPageViewData.dynamic || 'false' + /* The existence of a referrer parameter indicates that the page has been dynamically updated via an AJAX request + and therefore we can use it to set the dynamic property appropriately. This value is used by PA's to differentiate + between fresh page loads and dynamic page updates. */ + dynamic: referrer ? 'true' : 'false' } } window.GOVUK.analyticsGa4.core.sendData(data) diff --git a/docs/analytics-ga4/ga4-ecommerce-tracker.md b/docs/analytics-ga4/ga4-ecommerce-tracker.md index 29ccbaa280..60934712d9 100644 --- a/docs/analytics-ga4/ga4-ecommerce-tracker.md +++ b/docs/analytics-ga4/ga4-ecommerce-tracker.md @@ -17,16 +17,24 @@ In `analytics-ga4.js`: In `live_search.js` in the `finder-frontend` repository (https://github.com/alphagov/finder-frontend/blob/main/app/assets/javascripts/live_search.js#L129): ```JavaScript -GOVUK.analyticsGa4.Ga4EcommerceTracker.init(dynamicPageViewData) - -/* The init() function takes an object (dynamicPageViewData) as an optional parameter to detect whether dynamic updates have been made to the page via AJAX requests. The values in the object are then used to determine what is pushed to the dataLayer. If a parameter is not passed, this indicates a fresh page load (e.g. by refreshing the page or using the pagination) and that the page has not been dynamically updated via JS. */ +GOVUK.analyticsGa4.Ga4EcommerceTracker.init(referrer) ``` +The init() function takes a string (`referrer`) as an optional parameter to detect whether dynamic updates have been made to the page via AJAX requests. The presence of the `referrer` parameter is used to determine what is pushed to the dataLayer. If a parameter is not passed, this indicates a fresh page load (e.g. by refreshing the page or using the pagination) and that the page has not been dynamically updated via JS. + Unlike the other GA4 tracking scripts in this repository, ecommerce tracking is not initialised by `init-ga4.js`. Instead, it is initialised by the JS that runs on finder pages (specifically, the `LiveSearch.prototype.Ga4EcommerceTracking()` function). It is called: -On page load (where no parameters are passed) - https://github.com/alphagov/finder-frontend/blob/main/app/assets/javascripts/live_search.js#L55 +On page load (where no parameters are passed) e.g. + +``` +this.Ga4EcommerceTracking() +``` + +And whenever search results are updated (where a string parameter is passed) e.g. -And whenever search results are updated (where an object parameter is passed) - https://github.com/alphagov/finder-frontend/blob/main/app/assets/javascripts/live_search.js#L121 +``` +this.Ga4EcommerceTracking(this.previousSearchUrl) +``` Note: ecommerce tracking will only run if there is an element which has the `data-ga4-ecommerce` attribute. If the script can't find an element with this attribute, it will stop running. @@ -34,7 +42,7 @@ Note: ecommerce tracking will only run if there is an element which has the `dat ### On page load -Upon initialisation, the ecommerce tracker script will first detect whether a new page has been loaded (this is determined by the presence of an object parameter that `LiveSearch.prototype.Ga4EcommerceTracking()` passes to `Ga4EcommerceTracker.init()`). If `Ga4EcommerceTracker.init()` does *not* receive a parameter, this indicates that a new page has been loaded (i.e. the user has conducted a new search or has navigated to a new page using the pagination) and the initial set of search results that is loaded is pushed to the `dataLayer`. +Upon initialisation, the ecommerce tracker script will first detect whether a new page has been loaded (this is determined by the presence of the `referrer` parameter that `LiveSearch.prototype.Ga4EcommerceTracking()` passes to `Ga4EcommerceTracker.init()`). If `Ga4EcommerceTracker.init()` does *not* receive a parameter, this indicates that a new page has been loaded (i.e. the user has conducted a new search or has navigated to a new page using the pagination) and the initial set of search results that is loaded is pushed to the `dataLayer`. For example, if a user searches for "tax", the following object will be pushed to the `dataLayer` on page load: @@ -82,7 +90,7 @@ Then if the user applies the "Corporate information" topic filter and sorts by n `https://www.gov.uk/search/all?keywords=tax&level_one_taxon=a544d48b-1e9e-47fb-b427-7a987c658c14&order=updated-newest` -To track these changes to the URL, a new `page_view` object is sent to the `dataLayer` along with the updated search results so that the user journey can be tracked. In addition to this, PA's also need to be able to differentiate between a dynamic page update and a fresh page load; this is why the `dynamicPageViewData` object is passed on dynamic page updates and allows the `page_view.referrer` and `page_view.dynamic` to be set appropriately. +To track these changes to the URL, a new `page_view` object is sent to the `dataLayer` along with the updated search results so that the user journey can be tracked. In addition to this, PA's also need to be able to differentiate between a dynamic page update and a fresh page load; this is why the `referrer` parameter is passed on dynamic page updates and allows the `page_view.referrer` and `page_view.dynamic` to be set appropriately. Note: currently, filters that have been applied are not tracked; only the `search_results.ecommerce.items` and `search_result.sort` properties are updated. diff --git a/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.spec.js b/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.spec.js index 2f13f11c75..678ad6782f 100644 --- a/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.spec.js +++ b/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.spec.js @@ -193,10 +193,7 @@ describe('Google Analytics ecommerce tracking', function () { describe('when a new page isn\'t loaded e.g. when the user selects a filter', function () { it('should push a nullified ecommerce object to the dataLayer', function () { - GOVUK.analyticsGa4.Ga4EcommerceTracker.init({ - referrer: 'test', - dynamic: 'true' - }) + GOVUK.analyticsGa4.Ga4EcommerceTracker.init('test') expect(window.dataLayer[1].search_results.ecommerce).toBe(null) }) @@ -218,10 +215,7 @@ describe('Google Analytics ecommerce tracking', function () { } } - GOVUK.analyticsGa4.Ga4EcommerceTracker.init({ - referrer: 'https://gov.uk/', - dynamic: 'true' - }) + GOVUK.analyticsGa4.Ga4EcommerceTracker.init('https://gov.uk/') expect(window.dataLayer[0].event).toBe(pageViewExpected.event) expect(window.dataLayer[0].page_view.location).toBe(pageViewExpected.page_view.location) diff --git a/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.spec.js b/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.spec.js index 09d13f21ee..fbec8c2a8f 100644 --- a/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.spec.js +++ b/spec/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.spec.js @@ -313,7 +313,7 @@ describe('Google Tag Manager page view tracking', function () { expect(window.dataLayer[0]).toEqual(expected) }) - describe('correctly sets the referrer and virtual_page_view properties', function () { + describe('correctly sets the referrer and dynamic properties', function () { it('when not passed a parameter', function () { GOVUK.analyticsGa4.analyticsModules.PageViewTracker.init() @@ -322,31 +322,9 @@ describe('Google Tag Manager page view tracking', function () { it('when passed a parameter for the referrer', function () { expected.page_view.referrer = 'https://gov.uk/referrer' - GOVUK.analyticsGa4.analyticsModules.PageViewTracker.init({ - referrer: 'https://gov.uk/referrer', - dynamic: null - }) - - expect(window.dataLayer[0]).toEqual(expected) - }) - - it('when passed a parameter for the virtual_page_view', function () { expected.page_view.dynamic = 'true' - GOVUK.analyticsGa4.analyticsModules.PageViewTracker.init({ - referrer: null, - dynamic: 'true' - }) - expect(window.dataLayer[0]).toEqual(expected) - }) - - it('when passed a parameter for the virtual_page_view and referrer', function () { - expected.page_view.referrer = 'https://gov.uk/referrer' - expected.page_view.dynamic = 'true' - GOVUK.analyticsGa4.analyticsModules.PageViewTracker.init({ - referrer: 'https://gov.uk/referrer', - dynamic: 'true' - }) + GOVUK.analyticsGa4.analyticsModules.PageViewTracker.init('https://gov.uk/referrer') expect(window.dataLayer[0]).toEqual(expected) })