Setting up Segment Analytics with a Rails/React App

Alena Dagneau
Make School
Published in
4 min readJan 19, 2017

Recently at Make School, we wanted to set up Segment analytics with our Rails/React codebase. This means that we wanted to access the analytics object in the Rails HTML views but also inside the React classes. That meant, that the library needed to be loaded in at the highest possible level and the library itself attaches itself to the global window object.

The Wrong Way

Following Segment’s own instructions to using the analytics.js script for non-Rails specific apps, we copied the script including the HTML script tags and put it inside our main.html.erb file (and our React entry files, see more below) along this line:

Rails main.html.erb page:<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
!function(){var analytics=window.analytics=window.analytics||[];
/* ...shortened for brevity, see their instructions ... */
analytics.SNIPPET_VERSION="4.0.0";
analytics.load("YOUR_WRITE_KEY");
analytics.page();
}}();
</script>
<%= javascript_include_tag 'jquery' %>
</head>
<body>
...
</body>
</html>

When using the library in this way, we then wanted to track an event on other pages. We did this by adding the HTML script tag to the relevant Rails product_college.html.erb page, like this:

Rails product_college.html.erb page:<article>
/* some content for my Product College page goes here... */
</article>
<script>
analytics.track('view_product_college_overview');
</script>

As the analytics library loaded in the HTML head tags, we expected that everything was just fine and could see that “some” events were firing in the Network tab.

The first call loads in the minified analytics library. The “p” call (named by Segment) is the page load event but the custom event we implemented wouldn’t show. Clearly something was wrong.

Naming convention is driven by Segment’s library but you can see the actual event call when you click on the request and check the parameters that are sent:

request parameters for our Product College Overview page

The Right Way

The previous setup doesn’t work in Rails apps because of the way the Rails asset pipeline loads in JavaScript. Talking to one of the Rails engineers, finally got us on the right track! Rather than including the analytics script as part of the main.html.erb file, it needs to be added as a third party library JavaScript file inside the vendor/assets/javascripts folder. We removed the script tags and just added the Javascript function as is inside a file named analytics.js in the above folder. Then we included the file in the main.html.erb file, like so:

Rails main.html.erb page:<!DOCTYPE html>
<html>
<head>
<%= javascript_include_tag 'analytics' %>
<%= javascript_include_tag 'jquery' %>
</head>
<body>
/* ... */
</body>
</html>

This also means that the library script doesn’t clutter up your main.html.erb file! And who doesn’t like clean code?

This is the only change we needed to implement to finally fire events in our Rails codebase. The example.html.erb page could stay like this and finally fires the expected events.

See how there’s now a new network call? That network call is the result of using analytics.track(‘view_product_college_overview’); on the HTML page.

React Specific Setup

Our React application is integrated separately from our Rails frontend, which means they have their own HTML entry files (that’s just our setup). This means we need to include the <%= javascript_include_tag ‘analytics’ %> separately in every entry HTML file, similar to the way we included it in the main.html.erb file. Then we can call the analytics.track function when needed. In the React component we do this either on page load or on a user interaction. Because the analytics library is loaded in via the HTML head tags, analytics is globally accessible and doesn’t need an import script.

React example.js file:componentDidMount() {
analytics.track('clicked_apply_button_on_xyz_page');
}
********************************************************************Example on user interaction for enrollment.js file:enrollUser() {
analytics.track('begin_enrollment');
/* ... more code... */
}
render() {
return {
<a className="button"
onClick={this.enrollUser}>Enroll Now
</a>
}
}

This took us a while to figure out because we couldn’t find any documentation on using the JS library within a Rails/React app, so hopefully this will help someone else!

Happy Coding (& Tracking)!

--

--