Picture of Michael Lee
:wave: Hey hey, I'm Michael Lee and this is my site about being a developer, being a dad and making side projects.
Sponsorship

Google Analytics gtag setup for Rails 5.2

Written on November 17, 2018

Google has made grabbing traffic data from your site super simple. Most of the time you can just copy and paste the tracking code from the Google Analytics site to your web property’s <head> tag and start receiving data about traffic to your site.

In a Rails application, the set up is a little more involved.

Grab gtag Google Analytics code

Before we get started, we’ll want to grab the Google Analytics tracking code which can be found on the Google Analytics site under Admin > Property > Tracking Info > Tracking Code.

The code should look something like this:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXX-X"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-XXXXXXXX-X');
</script>

You’ll also need your tracking ID, which should be on the same page. It should look like UA-XXXXXXXX-X where X are numbers.

Store tracking ID in your app’s encrypted credentials file

Starting from Rails 5.2, instead of using a file that isn’t tracked in your version control system, Rails provides an encryted credentials file that you can commit into source and make available to all instances where your application is running.

Since the analytics code is JavaScript code, the tracking ID will be exposed in a browser’s source, but it’s still good to store the tracking ID along with your app’s other credentials. As you can see in the Google Analytics code above, there are two instances of the tracking ID. You can have both instances make reference to the stored credential and then if you ever need to change the ID, you’ll only have to do it in one place and not worry about changing multiple sections of your code.

To add the tracking ID to your credentials file, you’ll first open up the credential file by running:

EDITOR="nvim" bin/rails credentials:edit

Where nvim is your text editor of choice. NeoVim is my editor of choice so that’s why I have EDITOR="nvim"

If your editor is a GUI-based editor such as Code or Atom, you’ll also want to pass --wait.

EDITOR="atom --wait" bin/rails credentials:edit

Passing --wait will cause Rails to wait until the editor closes the credential file before accepting the changes and saving the latest credentials.

Once the credentials file is open, you’ll want to add in an entry like:

google_analytics: UA-XXXXXXXX-X

Again where XXXXXXXX-X is your unique tracking ID. Then save and close the file.

In your command line you should see a confirmation message like this:

New credentials encrypted and saved.

Another indicator that new credentials have been added to your application is that Git will indicate changes in the encrypted file config/credentials.yml.enc.

Create a Google Analytics view partial

Next we’ll want to add the Google Analytics code snippet to the <head> script found in the application.html.erb file, but before we do, it’s good to create a partial and add the partial to the application file. In creating a partial, the analytics code is in a single file and is quicker to access if you ever want to reference it in your project.

For this example, I’ll place this partial into my layouts folder in a file name _google_analytics.html.erb.

.                              
└── app   
    └── views
        └── layouts
            └── _google_analytics.html.erb

Within the new partial we’ll want to paste this code:

<% if Rails.env.production? %>
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= Rails.application.credentials.dig(:google_analytics) %>"></script>
  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());

    gtag('config', '<%= Rails.application.credentials.dig(:google_analytics) %>');
  </script>
<% end %>

There are two things to point out in the code snippet above. First it’s <% if Rails.env.production? %> which tells Rails to only render this block in production environments and not when you’re running on your machine in development mode. The second is <%= Rails.application.credentials.dig(:google_analytics) %> which is how you get the tracking ID rendered from your application’s credentials to the Google Analytics code.

If you’ve got your Rails application set up to use Turbolinks, you’ll also need to set up an event listener to send the gtag API the page’s URL when Turbolinks loads a new page.

First create a file in your javascripts file, I’ll being using a file called google_analytics.js.erb.

.                               
└── app               
    └── assets            
        └── javascripts 
            └── google_analytics.js.erb

The reason for the .js.erb extension is that, we’ll be passing the Google Analytics tracking ID using Ruby syntax. If you leave the extension as just .js then you can’t pass the tracking ID from the application’s credentials.

The event listener looks like this:

document.addEventListener('turbolinks:load', function(event) {
  if (typeof gtag === 'function') {
    gtag('config', '<%= Rails.application.credentials.dig(:google_analytics) %>', {
      'page_location': event.data.url
    })
  }
})

What the event listener above does is, first to check if the turbolinks:load event is triggered. If so, then an if statement checks to see if a function of gtag is available by checking typeof gtag === 'function'. If a gtag function is available, then it calls the function and sends a pageview.

If we’re running our application in a development environment, the gtag code defined in our _google_analytics.html.erb partial won’t render, which means that the gtag function won’t be available when this snippet of JavaScript is reached. This ensures that pageviews won’t be sent in a development environment.

Add the partial

Now that we’ve got the Google Analytics code snippet in a partial and have an event listener set up in our JavaScript, all that’s left is to add the partial in our layout file.

# app/views/layouts/application.html.erb 
...
  <head>
    <title>Awesome application</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= render 'layouts/google_analytics' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
...

As you can see, I’ve placed the partial to render above the javascript_include_tag helper. This is so that if the application is being run on a production server, the Google Analytics code will be made available before the application’s compiled JavaScript is run.

Thanks for taking the time to read this article. I'd love to stay in touch and share more tips on programming and design and side projects. Sign up and I'll send you my articles straight to your email.
Previous post: Toggle word wrap in Vim