Using Google Analytics to track page views in an AngularJS single page application

Part of a Google Analytics traffic graph showing page views against time

If you're using Google Analytics to track page visits across your application, getting this working in an AngularJS application is a little bit more complicated than simply dropping the GA JavaScript provided by Google into your application and considering it done. Because AngularJS is a single page application, there aren't any browser initiated page navigations occurring that will kick the GA code into life to send a message back to Google so analytics can be updated. In short, GA will show one page event per session that will be for the default "landing" URL for your application.

Solving the problem

In order to solve this problem, we need to tell GA every time a new "URL" is visited which in the world of AngularJS means when the user does something that causes them to navigate from https://example.org/#/Page1 to https://example.org/#/Page2. One way to do this is to build a new service that reacts to the AngularJS $viewContentLoaded event and sends a message to GA. THis is achieved (see Googles documentation) by issuing a send command with a hitType of 'pageview', along with the URL of the page that's been landed on, for example:

ga('send', 'pageview', { page: '/Page2' } );

There are two other values that can be passed for a pageview, title and location, being the title of the page and the full URL respectively. For simplicities sake in this sample, I'm only sending the page value as this will work just as well to show what's happening and keeps the code a little bit more concise.

Without further ado, here's the GoogleAnalytics service that is responsible for sending pageview events to GA (if you're using something like ng-annotate then this code could be simplified somewhat, I'm not aware of any reason why it wouldn't work with that):

;(function()
{
    'use strict';
    
    angular.module('myApp', ['ng']).service('googleAnalytics', ['$rootScope', '$window', '$location', function($rootScope, $window, $location) 
      {
        this.track = function() 
        {
            $window.ga('send', 'pageview', { page: $location.url() });
        };
        
        $rootScope.$on('$viewContentLoaded', this.track);
      }
    ]);
}());

This code does assume that you've added the GA JavaScript to your page, have GA configured correctly, have plugged in a Tracking ID and have initialised GA as per the instructions provided by Google.

There's nothing too exciting, or even that interesting, in the code for the googleAnalytics service. It simply defines the service, exposes a single method called track which pokes GA with a stick and wires the $viewContentLoaded event up to the track method.

The last thing to do is to start it all moving by calling the track method when the application first runs:

angular.module('myApp').run(function(googleAnalytics)
{
    googleAnalytics.track();
});

Once this is done, each and every transitition from one "page" to another within your AngularJS application will result in a page view being recorded with Google Analytics. Problem solved!

About Rob

I've been interested in computing since the day my Dad purchased his first business PC (an Amstrad PC 1640 for anyone interested) which introduced me to MS-DOS batch programming and BASIC.

My skillset has matured somewhat since then, which you'll probably see from the posts here. You can read a bit more about me on the about page of the site, or check out some of the other posts on my areas of interest.

No Comments

Add a Comment