Skip to content

rails google analytics

Daniel Kehoe edited this page Jun 15, 2013 · 18 revisions

Analytics for Rails

by Daniel Kehoe

Last updated 15 June 2013

Website analytics for Rails applications. Google Analytics and alternatives. How to install Google Analytics with Rails 4.0 Turbolinks. Event tracking and more with Segment.io, Mixpanel, KISSmetrics and others.

If You Are New to Rails

If you’re new to Rails, see What is Ruby on Rails?, recommendations for a Rails tutorial, and a list of top resources for Ruby and Rails.

Follow on Twitter Follow @rails_apps on Twitter for updates and timely Rails tips.

From the RailsApps Project

The RailsApps project provides open source applications and detailed tutorials for Rails developers.

Introduction

Analytics services provide reports about website traffic and usage.

You’ll use the data to increase visits and improve your site. Analytics close the communication loop with your users; your website puts out a message and analytics reports show how visitors respond.

Google Analytics is the best known tracking service. It is free, easy to use, and familiar to most web developers. In this article you’ll learn how to add Google Analytics to a Rails application, specifically addressing a known problem with the Rails 4.0 Turbolinks feature.

We’ll look at two ways to install Google Analytics for Rails 4.0. First we’ll look at a conventional approach and see how Google Analytics works. Then I’ll show an alternative approach using the Segment.io service. The service provides an API to send analytics data to dozens of different services, including Google Analytics.

Google Analytics

A conventional installation of Google Analytics requires adding JavaScript to every page of the Rails application. This can accomplished by modfiying the application layout and adding additional JavaScript as an application asset.

First let’s look at how Google Analytics works.

How Google Analytics Works

To collect usage and traffic data, every web page must contain a snippet of JavaScript code, referred to as the Google Analytics Tracking Code. The tracking code snippet includes a unique website identifier named the Google Analytics Tracking ID, which looks like this: UA-XXXXXXX-XX. You will obtain the JavaScript snippet and Tracking ID from the Google Analytics website when you set up an account for your website.

The tracking code snippet loads a larger JavaScript file (a 20KB file named analytics.js) from the Google webserver that serves as a web beacon. The analytics.js file is downloaded once and cached for the remainder of the session; often, it is already cached and doesn’t need to be downloaded because a visitor has (very likely) visited another website that cached the file.

Before December 2009, Google’s JavaScript code could slow the loading of a page because page rendering could be blocked until the Google code finished downloading. Google introduced asynchronous JavaScript code to improve page performance. Now, the analytics.js file downloads in parallel with other page assets. Page rendering can begin before the analytics.js file is delivered. In practice, the analytics.js file is often already cached.

Google recommended placing the original (synchronous JavaScript) snippet immediately before the final </body> close tag because it could delay page loading. Now, Google recommends placing the new (asynchronous JavaScript) snippet immediately before the closing </head> tag because it has little effect on page loading.

Each time the browser displays a new page, the JavaScript code sends data to the Google Analytics service. The data includes the URL of the requested page, the referring (previous) page, and information about the visitor’s browser, language, and location.

Adding Google Analytics Tracking Code

There are five approaches to adding the Google Analytics tracking code to a Rails application:

  1. add the Google tracking code to the application layout
  2. add a partial included in the application layout
  3. use view helpers such as Benoit Garret’s google-analytics-rails gem
  4. use Rack middleware such as Lee Hambley’s rack-google-analytics gem
  5. add the Google tracking code to the asset pipeline

All these approaches work for Rails 3.2. It doesn’t matter to Google how the script gets injected.

Google Analytics for Rails 4.0

Google Analytics doesn’t work for a Rails 4.0 web application. To be more precise, it won’t work for all pages. It can be made to work with a workaround.

Rails 4.0 introduced a feature named Turbolinks to increase the perceived speed of a website.

Turbolinks makes an application appear faster by only updating the body and the title of a page when a link is followed. By not reloading the full page, Turbolinks reduces browser rendering time and trips to the server.

With Turbolinks, the user follows a link and sees a new page but Google Analytics thinks the page hasn’t changed because a new page has not been loaded.

You can disable Turbolinks by removing the turbolinks gem from the Gemfile. However, it’s nice to have both the speed of Turbolinks and Google Analytics tracking data. This article details a workaround for the Turbolinks problem.

Google Analytics Account

Viist the Google Analytics website to obtain a Tracking ID for your website. You’ll need to know the domain name of your website before you set up a Google Analytics account for your website.

Heroku is a popular hosting platform for Rails applications. If you’ve deployed to Heroku without a custom domain, your domain name will look like “myapp.herokuapp.com”. When you set up your account, use it for fields for “Website Name,” “Web Site URL,” and “Account Name.”

Accept the defaults when you create your Google Analytics account and click “Get Tracking ID.” Your tracking ID will look like this: UA-XXXXXXX-XX. You won’t need the tracking code snippet as it is provided below. But take a minute to compare the code that Google provides to make sure it hasn’t changed from what’s provided here.

You’ll check your Google Analytics account later to verify that Google is collecting data.

Add a Partial

The Google Analytics JavaScript snippet must be included on every page.

Ordinarily, JavaScript for every page goes in the app/assets/javascripts/application.js file. To resolve the Turbolinks problem, we want the Google Analytics JavaScript snippet to load after Turbolinks, so we’ll add it to the default application layout with a partial template.

A partial is similar to any view file, except the filename begins with an underscore character. We’ll save the file in a view folder and use the render keyword to insert the partial in the default application layout.

Create a file app/views/layouts/_footer.html.erb:

<script>
  (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-XXXXXXX-XX', 'herokuapp.com');
  ga('send', 'pageview');

</script>

This code should be identical to the tracking code snippet you were offered when you created your Google Analytics account (but check it to be sure).

You must replace UA-XXXXXXX-XX with your tracking ID.

This example was created for a website hosted on Heroku. The tracking code specifies the herokuapp.com domain but can be used on any herokuapp.com subdomain such as myapp.herokuapp.com. Change the domain if you are using a custom domain.

Modify the Application Layout

You may have one or more application layout files. You must add the partial to each application layout if you want to track all pages.

The default application layout is the file app/views/layouts/application.html.erb.

Add the partial to an application layout by including:

<%= render 'layouts/footer' %>

Note the underscore and file extension are dropped from the filename _footer.html.erb.

Here is a typical default application layout found in the file app/views/layouts/application.html.erb. This application layout is set up to use Twitter Bootstrap and includes a footer partial.

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= content_for?(:title) ? yield(:title) : "Learning Rails" %></title>
    <meta name="description" content="<%= content_for?(:description) ? yield(:description) : "Learning Rails" %>">
    <%= stylesheet_link_tag "application", :media => "all" %>
    <%= javascript_include_tag "application" %>
    <%= csrf_meta_tags %>
  </head>
  <body>
    <header class="navbar navbar-fixed-top">
      <nav class="navbar-inner">
        <div class="container">
          <%= render 'layouts/navigation' %>
        </div>
      </nav>
    </header>
    <main role="main">
      <div class="container">
        <div class="content">
           <div class="row">
            <div class="span12">
              <%= render 'layouts/messages' %>
              <%= yield %>
            </div>
          </div>
          <footer>
            <%= render 'layouts/footer' %>
          </footer>
        </div>
      </div>
    </main>
  </body>
</html>

You can learn more about the default application layout in an article about the Rails Default Application Layout.

With the footer partial in place, the Google Analytics JavaScript snippet will be added on every page.

Ordinarily, that’s all you need to send tracking data to Google Analytics. But we have to add a Turbolinks workaround for Rails 4.0.

Turbolinks Workaround

With Turbolinks, the Google Analytics JavaScript snippet is not sufficient to record a page visit for every page update. We’ll add a Turbolinks workaround.

The workaround should be loaded on every page and it can be included as an application-wide asset (it will load before Turbolinks).

Add the file app/assets/javascripts/analytics.js.coffee to include the Turbolinks workaround:

$(document).on 'page:change', ->
  if window._gaq?
    _gaq.push ['_trackPageview']
  else if window.pageTracker?
    pageTracker._trackPageview()

The manifest directive //= require_tree . in the file app/assets/javascripts/application.js insures that the Turbolinks workaround is included in the concatenated application JavaScript file. If you’ve removed the //= require_tree . directive, you’ll have to add a directive to include the Turbolinks workaround file.

The file contains Coffeescript, a programming language that adds brevity and readability to JavaScript. Turbolinks fires events to provide hooks into the lifecycle of the page. The page:change event fires when a page has been parsed and changed to the new version by Turbolinks. The code listens for the page:change event and calls either of two Google Analytics JavaScript methods that send data to Google Analytics.

This version of the workaround was initially suggested by Shuky Dvir on Nick Reed’s site Turbolinks Compatibility.

Deploy

If you wish to deploy to Heroku, you must recompile assets and commit to the Git repo:

$ git add -A
$ git commit -m "analytics"
$ RAILS_ENV=production rake assets:precompile
$ git add -A
$ git commit -m "assets compiled for Heroku"

Then you can deploy to Heroku:

$ git push heroku master

See the article Rails and Heroku for more on deploying to Heroku.

Log into your Google Analytics account to see real-time tracking of visits to your website. Under “Standard Reports” see “Real-Time Overview.” You’ll see data within seconds after visiting any page.

Segment.io

Segment.io is a subscription service that gathers analytics data from your application and sends it to dozens of different services, including Google Analytics. The service is free for low- and medium- volume websites, providing one million API calls (page views or events) per month at no cost. There is no charge to sign up for the service.

Using Segment.io means you install one JavaScript snippet and get access to reports from dozens of analytics services. You can see a list of supported services. The company offers helpful advice about which analytics tools to choose from. For low-volume sites, many of the analytics services are free, so Segment.io makes it easy to experiment and learn about the available analytics tools. The service is fast and reliable, so there’s no downside to trying it.

If you’ve followed instructions above and installed Google Analytics using the conventional approach, be sure to remove the code before installing Segment.io.

Accounts You Will Need

You will need an account with Segment.io. Sign up for Segment.io.

You will need accounts with each of the services that you’ll use via Segment.io.

You’ll likely want to start with Google Analytics, so get a Google Analytics account and tracking ID as described in the section Google Analytics Account above.

Installing the JavaScript Snippet

Segment.io provides a JavaScript snippet that sets an API token to identify your account and installs a script named analytics.js. This is similar to how Google Analytics works. Like Google Analytics, the Segment.io script loads asynchronously, so it won’t affect page load speed.

The Segment.io JavaScript snippet should be loaded on every page and it can be included as an application-wide asset.

Add the file app/assets/javascripts/analytics.js to include the Turbolinks workaround:

// Create a queue, but don't obliterate an existing one!
var analytics = analytics || [];

(function () {

  // A list of all the methods we want to generate queueing stubs for.
  var methods = [
    'identify', 'track', 'trackLink', 'trackForm', 'trackClick', 'trackSubmit',
    'page', 'pageview', 'ab', 'alias', 'ready', 'group'
  ];

  // For each of our methods, generate a queueing method that pushes arrays of
  // arguments onto our `analytics` queue. The first element of the array
  // is always the name of the analytics.js method itself (eg. `track`), so that
  // we know where to replay them when analytics.js finally loads.
  var factory = function (method) {
    return function () {
      analytics.push([method].concat(Array.prototype.slice.call(arguments, 0)));
    };
  };

  for (var i = 0; i < methods.length; i++) {
    analytics[methods[i]] = factory(methods[i]);
  }

}());

// Define a method that will asynchronously load analytics.js from our CDN.
analytics.load = function(apiKey) {

  // Create an async script element for analytics.js based on your API key.
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.async = true;
  script.src = ('https:' === document.location.protocol ? 'https://' : 'http://') +
                'd2dq2ahtl5zl1z.cloudfront.net/analytics.js/v1/' + apiKey + '/analytics.min.js';

  // Find the first script element on the page and insert our script next to it.
  var firstScript = document.getElementsByTagName('script')[0];
  firstScript.parentNode.insertBefore(script, firstScript);
};

// Load analytics.js with your API key, which will automatically load all of the
// analytics integrations you've turned on for your account. Boosh!
analytics.load('YOUR_API_TOKEN');

If you previously installed the file app/assets/javascripts/analytics.js.coffee, be sure to remove it.

You must replace YOUR_API_TOKEN with your Segment.io API token. You can find the API token on your “Settings” page when you log in to Segment.io (it is labelled “Your API Key”).

The manifest directive //= require_tree . in the file app/assets/javascripts/application.js insures that the Segment.io JavaScript snippet is included in the concatenated application JavaScript file. If you’ve removed the //= require_tree . directive, you’ll have to add a directive to include the app/assets/javascripts/analytics.js file.

Credits

Daniel Kehoe wrote the article.

Did You Like the Article?

Was this useful to you? Follow rails_apps on Twitter and tweet some praise. I’d love to know you were helped out by the article.

Any issues? Please leave a comment below.

Clone this wiki locally