Google Analytics for Single-Page Web Apps with Ember

Single-page web apps are awesome — they have so much flexibility and power. Unfortunately, when users browse a single-page web app, Google Analytics doesn’t work as intended when changing “pages”. Under the hood of these engines lies DOM manipulation to change what is displayed on screen, but Google Analytics watches for page changes. Fortunately, “Ember”:http://emberjs.com/ makes it easy to hook into the “page changes” to allow for tracking.

The implementation is fairly simple — you need an initializer and the standard Google Analytics tracking snippet. As normal, follow the instructions to place the analytics code into your index.html. If you are serving up you app through Rails or another engine that builds your pages, place the code in the page that loads your Ember files. The code should look similar to this:

  (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-X', 'example.com');
  ga('send', 'pageview');

Once you have that in place, you can place this code into your initializers:

Ember.GoogleAnalyticsTrackingMixin = Ember.Mixin.create
  pageHasGa: ->
    window.ga and typeof window.ga is "function"

  trackPageView: (page) ->
    if @pageHasGa()
      unless page
        loc = window.location
        page = (if loc.hash then loc.hash.substring(1) else loc.pathname + loc.search)
      ga "send", "pageview", page

  trackEvent: (category, action) ->
    ga "send", "event", category, action  if @pageHasGa()

Ember.Application.initializer
  name: "googleAnalytics"
  initialize: (container, application) ->
    router = container.lookup("router:main")
    router.on "didTransition", ->
      @trackPageView @get("url")

Ember.Router.reopen Ember.GoogleAnalyticsTrackingMixin

The initializer will run and inject a tracking object into the Ember router. When the Ember router changes views, much like a page change, it will then check if the window.ga object is available (the Google Analytics code we placed earlier) and fire off a page change message. With the available “Google Analytics API”:https://developers.google.com/analytics/devguides/collection/analyticsjs/, you can now track events and other things throughout your Ember app by using the window.ga object.
 

Conversation
  • ziga says:

    cool. but this approach from ember guides seems even more straight forward to me

    • Jared Sartin Jared Sartin says:

      True, their method is a little more precise. My method does checking for Google Analytics being defined on the page, so you don’t get errors if it breaks or just doesn’t get included. It also sets up the event sending (which is simple in GA, but is a bit more abstracted here).

      Thanks for the link. That content was not around when I initially wrote the script, and I had not looked to see if that was around since!

  • anon says:

    The ember official guides way does seem much simpler. But I definitely appreciate seeing another way of doing it. So thank you for that.

  • Mikeumus says:

    I do like the page GA code checking, definitely going to use it in my implementation. Thanks Jared.

    Alex DiLiberto gave a really nice talk about a robust & scalable way of adding Google Analytics to an ember app in his EmberConf 2014 talk here. – SlidesGitHub


    App.ApplicationRoute = Ember.Route.extend({
    actions: {
    didTransition: function() {
    Ember.run.once(this, function() {
    ga('send', 'pageview', this.router.get('url'));
    });
    }
    }
    });

    The talk was aiming to be independent of which analytics library was used.

  • Comments are closed.