Turbolinks, Google Analytics, and Tracking
May 20, 2016
Turbolinks and Google Analytics
Turbolinks does not play well with Google Analytics’ recommended setup. I thought I had fixed Google Analytics(which I will refer to as GA from now on) tracking awhile back. My assumption was that adding analytics.js
inside the <head>
tag, and adding the following snippet right before the closing </body>
tag would work:
<script>
ga('send', 'pageview');
</script>
I thought that by adding the snippet, every time a page is swapped in by turbolinks the script should run and send GA a hit. This is not true. The location
of the current page is not sent. Instead, the location
of the first page that loaded the GA script is sent. This is because location
is set when analytics.js
creates the tracker for the current page1. In a website without turbolinks where every redirect to another page is a complete refresh, analytics.js
is reloaded, g('create', 'UA-XXXXX-Y', 'auto');
is called, and the location
is properly set. To fix this, I just needed to modify the data that I sent to GA. Instead of just calling ga('send', 'pageview')
, I set all my fields explicitly.
<script>
ga('send', {
hitType: 'pageview',
title: document.title,
location: location.href.split('#')[0],
page: location.pathname,
transport: 'beacon',
});
</script>
Tracking clicks to my resume
My resume link opens a PDF. There’s no way for me to run Javascript to send a pageview to GA, so I have to send a pageview right as the user clicks the link. This is simple, and there are lots of guides on Google about this behavior. It’s called an outbound link, but in my case, it’s a link to a page that cannot execute Javascript. I used the following snippet to achieve this.
<script>
var resumePath = '/assets/resume.pdf'
var trackResumeLink = function() {
if (window.ga && ga.loaded) {
ga('send', {
hitType: 'pageview',
title: 'resume.pdf',
location: location.origin + resumePath,
page: resumePath,
transport: 'beacon',
hitCallback: function() { document.location = location.origin + resumePath; }
});
} else {
document.location = location.origin + resumePath;
}
}
</script>
And the on the resume link itself, I added an onclick
event handler.
<a href="/assets/resume.pdf" onclick="trackResumeLink(); return false;" class="nav-link">