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

Begin migration from classic to universal Google Analytics #549

Merged
merged 24 commits into from
Feb 25, 2015

Conversation

fofr
Copy link
Contributor

@fofr fofr commented Feb 23, 2015

This PR puts a facade in front of the Google Analytics classic and universal APIs (GOVUK.analytics), so that we can track events, pageviews and dimensions identically in both (eg GOVUK.analytics.trackEvent, GOVUK.analytics.trackPageview, GOVUK.analytics.setDimension).

  • It manages the loading of analytics libraries and configuration of the tracker profiles from a file, rather than a template, avoiding repetition of this code on every page and allowing it to be minified and cached.
    • These files are bundled with our other JS and continues to be loaded at the foot of the page (a separate test will be conducted to assess the differences between tracking code placement at the top and bottom)
  • Slimmer is inserting custom variables into a script tag, while this isn't ideal a choice has been made to leave this as-is for now and tackle separately. To account for Slimmer using only the classic API a shim has been put in place.
  • All custom events, custom variables and pageviews within static are now tracked in both universal and classic
  • Any use of the analytics API within apps that hasn't been updated to use GOVUK.analytics should be unaffected, they just won't be tracking to Universal yet. There are stories to update them.
  • The GOVUK.sendToAnalytics method has been removed

An analysis of the state of analytics across GOV.UK is available as a Google Doc:
https://docs.google.com/a/digital.cabinet-office.gov.uk/document/d/1Tga2eA0uP2hiVuLQW6nyWOuOLmhdekGE6fs_DPec0BM/edit?usp=sharing

fofr added 21 commits February 18, 2015 15:55
* Create classic and universal analytics trackers that can load their
tracking code, track custom events, track page views – virtual and
otherwise, and set custom dimensions/variables
* Create a GOVUKTracker that let’s us track to both classic and
universal simultaneously
Cleanup method declaration and improve readability.
Avoid pushing to an undefined array by creating that array when the
tracker is created.
When starting a tracker, set custom dimensions before the initial
pageview is tracked.
 A cookie is sometimes set by apps to declare the GA parameters that
should run on the subsequent page. These declare the actual methods to
call in classic analytics. This is a temporary shim to ensure these are
applied to both classic and universal before updating apps.

* Pull cookie code from current analytics snippet
* Modify to go through setDimension rather than directly to GA
* Parse index and scope variables as integers
Analytics and the loading of the libraries is now within a cacheable,
compressible JS file. Avoid repeating this javascript on every page.

* Include a comment indicating that slimmer is still inserting custom
variables
Slimmer inserts classic custom variables into the ga-params script tag,
we need to intercept these and track them in both universal and
classic. (Slimmer is being left alone for the time being)

* Intercept the classic analytics queue _gaq before initialising
analytics
* Use this queue after initialisation to setup custom variables before
the initial pageview
* Move the google_analytics include to load before the application
javascript so the slimmer variables can be distinguished from those
added later
* Compress the javascript within ga-params element
Load analytics libraries, then configure tracker and track first
pageview
Allow events to mark themselves as non-interactive so they do not
affect the page bounce rate.

Currently being used by the scroll tracker.
* Put events through tracker.trackEvent rather than “sendtoAnalytics”
The global ga function might not be available if the analytics script
couldn’t be loaded, or if the user is blocking the script from loading
(eg Adblocking)

* Proxy calls to ga via a `sendToGa` function which tests for the
presence of the global function first.
Rename the tracker object to make usage simpler and easier. Calling
GOVUK.analytics.trackEvent is easier to remember and use.
Switch to using GOVUK.analytics.trackEvent so that events go to both
classic and universal analytics profiles.
sendToAnalytics was compatible with only the classic tracker. Its uses
have already been replaced with GOVUK.analytics.trackEvent (user
satisfaction survey and scroll tracker).
`Analytics` suggests that it’s a constructor, it’s not.
Objects are typically specific enough to not require a namespace.

* Rather than renaming `Analytics`, which is being used in Slimmer,
remove the namespacing altogether.
Switch to GOVUK.analytics.trackEvent.
Allow tracking to work in dev, preview and staging by customising the
cookie domain when it doesn’t match www.gov.uk.
Modules may depend on GOVUK.analytics being present. To ensure this the
analytics module should be loaded first. (eg user satisfaction survey)

This will also trigger the analytics libraries to load sooner, and
reduce the time to initial pageview.
There is no equivalent of `setAutoLink` in Universal. The stubbed
functions, added to ensure equivalence with classic, can be removed.

* Remove stub function
@edds
Copy link
Contributor

edds commented Feb 23, 2015

Is it worth changing the interface of GOVUK.analytics.trackEvent so that it takes an object rather than arguments?

So instead of:

GOVUK.analytics.trackEvent('browser-check', 'prompt-shown', '', 1, true);

Something like:

GOVUK.analytics.trackEvent('browser-check', {
  action: 'prompt-shown', 
  label 'thing',
  value: 1,
  noop: true
});

And then have the label, value and noop to be optional. That way I can work out what the arguments mean without having to look them up.

Label, value and nonInteraction are optional. Provide these optional
arguments using an options object with named members. This makes it
easier to see what values like “1” and “true” mean.

Action and category are required so have been left as parameters.
@fofr
Copy link
Contributor Author

fofr commented Feb 24, 2015

@edds, yes, it is worth it. Updated in df477da

The first two parameters are required, category and action. Optional arguments are now passed in through an options object:

GOVUK.analytics.trackEvent('category', 'action', {
  label: 'label',
  value: 1,
  nonInteraction: true
});

@edds
Copy link
Contributor

edds commented Feb 25, 2015

Thank you for that @fofr. My only other concern is the interface to the Tracking object and the requirement to have both a universal and classic tracking codes in the initialisation. In theory if we start using this code for other projects that could be an issue. Though its probably beyond the scope of this and as all our instantiation is happening in this project I am happy for this to be merged as is.

Unless @dsingleton, @alicebartlett, @bradleywright et al. have any large concerns I am happy for this to get merged so we can start iterating.

"use strict";
window.GOVUK = window.GOVUK || {};

var Tracker = function(universalId, classicId, cookieDomain) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be better to make these passed as an object? That way turning off classic analytics would just require us to drop the argument from the code where it's initialised rather than rewrite all of this.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 please

@bradwright
Copy link
Contributor

I've commented on one thing, which @edds already referenced. Otherwise 👍

@jabley
Copy link
Contributor

jabley commented Feb 25, 2015

We'll need to update spotlight with a similar change. I spoke to @fofr in the frontend meeting today about it.

@fofr
Copy link
Contributor Author

fofr commented Feb 25, 2015

I've updated the Tracker constructor to take an object with named parameters in ff058c2

Avoid having to know the slot and name for a dimension. Pass in only
the value that changes.
benilovj added a commit that referenced this pull request Feb 25, 2015
Begin migration from classic to universal Google Analytics
@benilovj benilovj merged commit 483cd8d into master Feb 25, 2015
@benilovj benilovj deleted the extracted-ga branch February 25, 2015 13:34
@benilovj
Copy link
Contributor

Great work!

@dsingleton
Copy link
Contributor

Very happy with the approach here. Great work @fofr

benilovj added a commit to alphagov/whitehall that referenced this pull request Feb 26, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.
benilovj added a commit to alphagov/whitehall that referenced this pull request Feb 26, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.
benilovj added a commit to alphagov/smart-answers that referenced this pull request Feb 26, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.

This also removes a commented out line.
benilovj added a commit to alphagov/smart-answers that referenced this pull request Feb 26, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.

It's possible that `GOVUK.analytics.trackEvent` isn't loaded yet because it's
loaded in another JS file, but since the analytics call happens after the function changing
the browser state, its failure wouldn't impact the user, and it's preferable in this case
to not hide the error.

This commit also removes a commented out line.
benilovj added a commit to alphagov/frontend that referenced this pull request Feb 26, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.
benilovj added a commit to alphagov/smart-answers that referenced this pull request Feb 26, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.

This commit also removes a commented out line.
russellthorn pushed a commit to alphagov/frontend that referenced this pull request Feb 27, 2015
We are currently in the process of moving over to use universal
analytics. This change updates live search to use both classic and
universal. The plan is to get universal analytics monitoring exactly
what classic currently does.

This change uses GOVUK.analytics from Paul hayes recent work on static
alphagov/static#549
As suggested by Paul we removed the last figure of 3 because that is
the default figure for that and is not needed.

https://www.pivotaltracker.com/story/show/87738926
benilovj added a commit to alphagov/smart-answers that referenced this pull request Mar 2, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.

This commit also removes a commented out line.
benilovj added a commit to alphagov/smart-answers that referenced this pull request Mar 2, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.

This commit also removes a commented out line.
benilovj added a commit to alphagov/whitehall that referenced this pull request Mar 2, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.
benilovj added a commit to alphagov/whitehall that referenced this pull request Mar 2, 2015
https://www.pivotaltracker.com/n/projects/1261204/stories/88175032

This change wraps the GA event in the [newly introduced](alphagov/static#549)
analytics API. This will aid in the migration from GA Classic to Universal Analytics, while
remaining functionally equivalent during the migration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants