SPAs

Tips for Tracking in Single Page Applications

Installing tracking code in Single Page Applications is slightly more complicated in that you cannot simply copy the tracking code and paste it into your page <head>. This is because the idea of a SPA is that the page head is not reloaded all the time, but rather just parts of the page are updated based on data-only (not full page html) requests made in the background.

If you have developers implementing custom event tracking, you shouldn't have a problem with this, as an SPA developer should be intimately familiar with this issue as it's core to the concept of SPA's.

Suggestions

The Snippet and the Config: in the <head>

You'll probably still want to load the The Javascript Snippet in your page <head>, along with your tracker configuration (e.g.: woopra.config()). You'll be unable to track all of your user's behavior if you simply put your tracking code (e.g.: woopra.track()) in the <head> area though because it will only run once at page load, and subsequent actions taken by the user in your web-app will not be automatically re-tracked.

Where to Track

This means you will have to implement some level of custom tracking, even if you aren't creating custom events, you will still need to put your calls to woopra.track() into the event handler functions that are relevant. For instance, if you run a media content site, and you have a handler function that runs when a new article is loaded, THAT is where you want to put your call to woopra.track(), maybe even while you're at it, adding a custom event to the call:

woopra.track('article view', {
    author: 'Ralph Samuel',
    topic: 'Tracking Implementations',
    title: document.title,
    url: window.location.href
})

Example Code

/*
 * Tracking pushState browser history
 */
window.history.pushState = new Proxy(window.history.pushState, {
  apply: function(target, thisArg, argArray) {
    var output = target.apply(thisArg, argArray);

    var event = new CustomEvent('woopraUrlHistory', {
      isBack: false,
      path: window.location.path
    });

    window.dispatchEvent(event);

    return output;
  }
});

window.addEventListener('popstate', function(e) {
  var event = new CustomEvent('woopraUrlHistory', {
    isBack: true,
    path: window.location.path
  });

  window.dispatchEvent(event);
});

window.addEventListener('woopraUrlHistory', function(e) {
  woopra.track('pv', { isPush: true, isBack: e.isBack }, { lifecycle: 'page' })