On a mobile web app we are working on we wanted to track every page view on the inside of the jQuery Mobile framework.

We ran into a bit of an issue doing that due to how pages are handled within jQuery Mobile. Page loads are not true hard reloads. Instead, they are dynamically inserted into the DOM. That’s a problem for the traditional Google Analytics tracking code.

The Solution

in the root layout of the site we add GA tracking snippet

      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', "#{ENV['GA_TRACKING_ID']}"]);
      _gaq.push(['_setDomainName', 'none']);
      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

Then we created a new page_tracker.coffee file that is included in the head of the page:

fireTracker = () ->
    hash = location.hash
    if hash
      _gaq.push(['_trackPageview', hash.substr(1)]);
      _gaq.push(['_trackPageview', location.pathname]);
  catch err

Then, within the header we simply added this bit of code:

$($(document).on('pageshow', fireTracker));

This only binds to the pageshow event for the document which prevents a buildup of DOM elements triggering the show event.

—Sam Saccone