Google Analytics
for Web Developers
The features you're not using,
but probably should be.
Philip Walton /
philipwalton.com /
@philwalton
Question:
How many people here use Google Analytics?
How many of you do more than just copy and paste the JavaScript tracking snippet?
How did we get here?
Websites used to be so simple.
One request. One pageview. The End.
Now the web stack is extremely complex, and sites are more interactive than ever.
Yet most developers still just copy and paste the snippet, which only tracks a few basic metrics.
The goals of this talk
I know I can't possibly teach you everything about Google Analytics in 45 minutes.
Instead, I hope to get you thinking, show you some things you may not have seen, and inspire you to learn more on your own.
Fundamentals
The Analytics Data Model
Users → Sessions → Hits
- A user is an individual who visits your site or application.
- A session is one or more interactions (or hits) that take place on your site within a given time frame.
- A hit is a single user interaction. All data that gets since to Google Analytics is in the form of hits.
One or more hits belong to a session, and one or more sessions belong to a user.
What does a hit look like?
For example:
https://www.google-analytics.com/collect?v=1&t=pageview&tid=UA-70063124-1&cid=1715546980.1443552756&dl=http%3A%2F%2Fwww.example.com&ul=en-us&de=UTF-8&dt=Test%20Page&sd=24-bit&sr=2560x1600&vp=1265x869&je=1&fl=19.0%20r0
Dimensions & Metrics
A metric is a quantitative measurement. It's always a numeric type. (Session, Pageviews)
A dimension is a cross-section of a metric. It's usually a string. (Browser, Country)
Dimensions and metrics can be scoped to a:
- User (Users, User Type)
- Session (Bounces, Referrer)
- Hit (Total Events, Event Category)
Features
Tracking pageviews
You can use pageview tracking to find out what pages people are visiting on your site.
Pageview tracking is included in the JavaScript tracking snippet.
The JavaScript tracking snippet
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
What does this code actually do?
When in doubt, use the debugger!
The debug version of analytics.js makes it easy to see exactly what's going on under the hood:
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/**analytics_debug.js**','ga');
Debugger demo →
Cool, so pageview tracking code is included in the default JavaScript tracking snippet, which means I don't have to worry about it…right?
Dun, dun, dun!
What about Single Page Applications?
The snippet tracks the initial pageview, but does it also listen for changes to the URL and track those?
Let's find out →
When building single page applications, it's important to always update your tracker objects whenever any page-related data changes.
Learn more →
Tracking events
You can use event tracking to capture generic user interactions that happen during a session.
Event hits contain the following dimensions:
- Event category
- Event action
- Event label
Usage
ga('send', 'event', {
eventCategory: 'Outbound link',
eventAction: 'click',
eventLabel: link.href
});
or...
ga('send', 'event', 'Outbound Link', 'click', link.href);
This code tracks click events on links to external sites:
ga('create', 'UA-12345-1', 'auto');
$(document).on('click', 'a', function() {
if (this.hostname != location.hostname) {
**ga('send', 'event', 'Outbound Link', 'click', this.href);**
}
});
Setting the transport to "beacon" will ensure hits are always sent. Fall back to opening in a new tab.
ga('create', 'UA-12345-1', 'auto');
**ga('set', 'transport', 'beacon');**
$(document).on('click', 'a', function() {
if (this.hostname != location.hostname) {
**if (!navigator.sendBeacon) this.target = '_blank';**
ga('send', 'event', 'Outbound Link', 'click', this.href);
}
});
View demo →
Tracking performance
You can use user timing tracking to measure how long it takes something to happen.
Timing hits contain the following dimensions:
- Timing category
- Timing variable
- Timing label
And the following metric:
Usage
ga('send', 'timing', {
timingCategory: 'Fonts',
timingVar: 'load',
timingValue: elapsedTime, // Up to you to calculate
timingLabel: 'fonts.googleapis.com'
});
or...
ga('send', 'timing', 'Fonts', 'load', elapsedTime, 'fonts.googleapis.com');
This code tracks how long it takes to load Google Web Fonts on your site using webfont.js:
<script async src="//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
<script>
performance.mark('fonts:start');
WebFontConfig = {
google: { families: ['Lobster::latin'] },
active: function() {
performance.mark('fonts:end');
performance.measure('fonts:load', 'fonts:start', 'fonts:end')
var fontsLoad = performance.getEntriesByName('fonts:load')[0];
**ga('send', 'timing', 'Fonts', 'load', fontsLoad.duration);**
}
};
</script>
User timing demo →
Tracking exceptions
You can use exception tracking to discover when your code fails in unexpected ways.
Exception hits contain the following dimensions:
- Exception description
- Exception fatal?
Usage
ga('send', 'exception', {
exDescription: error.message
exFatal: false // Optional
});
This code tracks any errors in the following function:
try {
someFunctionThatIsKnownToBeFlaky();
}
catch(error) {
**ga('send', 'exception', {exDescription: error.message});**
}
Exception demo →
As JavaScript Promises gain popularity, exception tracking for asynchronous code will be as easy as appending a .catch()
handler to a promise chain:
fetch('/my-api-endpoint.json')
.then(convertResultToTsv())
.then(saveDataToTheDataStore())
.then(informAnyListeners())
.catch(function(error) {
**ga('send', 'exception', {exDescription: error.message});**
});
You can even track "uncaught" exceptions:
window.onerror = function(message, url, line, col) {
var desc = message + ' (' + line + ':' + col + ') URL: ' + url;
**ga('send', 'exception', {exDescription: desc});**
};
What if there's something I want to track
that's not built in to Google Analytics?
Defining your own
dimensions & metrics
You can create custom dimensions & metrics to track and categorize data not already captured by Google Analytics.
Custom dimensions & metrics are just like regular dimensions and metrics, but they're user-defined.
Examples of a custom dimension
- Logged-in status
- User demographics (gender, age)
- Network status (online, connection type)
- Session context (custom media, ambient light)
Examples of a custom metric
- Score in a game
- Word count of a comment
- Success rate of an action
Breakpoint tracking
When building a responsive website using media queries, it's important to know what media query is active.
This is data that viewport size and device type alone cannot accurately tell you.
The active media query is just another dimensions you can track!
Using custom dimensions
- Step 1: define the custom dimension.
- Step 2: capture the data and send it to Google Analytics.
- Step 3: set up a report to view the results.
var breakpoints = {
sm: '(max-width: 767px)',
md: '(min-width: 768px) and (max-width: 991px)',
lg: '(min-width: 992px) and (max-width: 1199px)',
xl: '(min-width: 1200px)'
};
Object.keys(breakpoints).forEach(function(breakpoint) {
var mql = window.matchMedia(breakpoints[breakpoint]);
if (mql.matches) {
**ga('set', 'dimension1', breakpoint);**
}
});
Breakpoint tracking example →
Learn more →
Custom Reporting
If you're sending custom data to Google Analytics, it's essential that you know how to report on that data.
Examples
- Outbound link clicks
- Breakpoint usage
- Font load times & errors
- Exceptions
Open Google Analytics →
Filters vs. Segments
A filter eliminates rows from the result set returned by a query.
A segment narrows the original data that the query operates on.
Final thoughts
As the web changes and becomes more complex, it gets harder and harder to rely on one-size-fits-all solutions.
Measuring user interaction is critical to making informed decisions about your site or application.
As you're attending the talks, and learning about new technologies, keep these analytics concepts in mind.
The End
- Twitter
- @philwalton
- Website
- philipwalton.com
- Github
- github.com/philipwalton
- Slides
- github.com/philipwalton/talks