Google Analytics: How to track pages in a single page application?

17,876

Solution 1

If you are using the newer analytics.js API, Google's documentation requires the following code to trigger the event:

ga('send', 'pageview', '/some-page');

If you are using the older ga.js API, David Walsh suggests AJAX websites to use the _gaq.push method:

_gaq.push(['_trackPageview', '/some-page']);

Solution 2

I know it's old question but since this question is first result in Google about tracking pushState() in Google Analytics and all answers are wrong I decided to answer it.

In other answers they mentioned to use directly ga('send' ..... ) but this is wrong way to do it.

First you have to 'set' parameters and then use 'send' to track it.

If you want to update only url, use following code

// set new url 
ga('set', 'page', '/new-page');

// send it for tracking
ga('send', 'pageview');

If you want to update url and title, add title parameter to it

// set new url and title
ga('set', {
  page: '/new-page',
  title: 'New Page'
});

// send it for tracking
ga('send', 'pageview');

Source Single Page Application Tracking - Web Tracking (analytics.js)

Solution 3

February 2018 Update - Global Site Tag (gtag.js)

Google Analytics has a new tracking code snippet, so the other answers might not work for gtag.

This is the default tracking code. It only runs once even though we try to run it each URL changes.

gtag('config', 'GA_TRACKING_ID');

But with a page_path parameter we can make GA run manually.

gtag('config', 'GA_TRACKING_ID', {'page_path': '/new-page.html'});

And we can make something like this.

var origin = window.location.protocol + '//' + window.location.host;
var pathname = window.location.href.substr(origin.length);
gtag('config', 'GA_TRACKING_ID', {'page_path': pathname});

Single page application tracking with gtag.js (Google documentation)

Solution 4

Recent answer (2017)

You can now use Google's autotrack.js, a script that enhances analytics.js.

It includes a plugin that automatically tracks URL changes for single page applications.

You just need to include the script and the following line in your html:

ga('require', 'urlChangeTracker');

Solution 5

2020 Update

If you are using Google Analytics 4 you don't need to push the event anymore IF you enabled the Page views option in the Enhanced measurement feature in Data Streams menu.

Enhanced measurement

Share:
17,876
Derek 朕會功夫
Author by

Derek 朕會功夫

Uh oh, sounds like somebody’s got a case of the Mondays! Are you using enough jQuery? http://i.stack.imgur.com/ssRUr.gif "Everybody stand back, I know regular expressions!" ─ xkcd 208

Updated on June 02, 2022

Comments

  • Derek 朕會功夫
    Derek 朕會功夫 almost 2 years

    Currently in my website, I used HTML5's pushState() and popState in links to increase the speed. However, this doesn't really change the real URL and it looks like it will affect and mess up the Google Analytics's code. (doesn't show a url change) Is there a possible solution for this? Thanks,

    • Dagg Nabbit
      Dagg Nabbit about 12 years
    • Derek 朕會功夫
      Derek 朕會功夫 about 12 years
      Never mind, found this.
    • G-Wiz
      G-Wiz over 10 years
      It does change the real URL. In browsers that support the History API, pushState should change the URL in the address bar and in the Location objection. What it doesn't do is change the loaded resource. That is up to you, and it's the whole point of the History API.
    • Derek 朕會功夫
      Derek 朕會功夫 over 10 years
      @gWiz - What I meant was that it is not requesting the new page like normal and the scripts didn't got reloaded.
    • Biswadeep Sarkar
      Biswadeep Sarkar over 3 years
      This article has the most decent explanation bounteous.com/insights/2018/03/30/…
  • Dagg Nabbit
    Dagg Nabbit about 12 years
    You still might want to look into event tracking, it's good for "ajaxy" apps. You can track a lot more than page views.
  • VinnyG
    VinnyG about 12 years
    so if you only change the url using pushState() and after that call _gaq.push(['_trackPageview') it won't work in GA?
  • ChaseMoskal
    ChaseMoskal over 10 years
    @VinnyG: More than a year later, with the new analytics.js sdk -- it will just work. More details in my answer.
  • G-Wiz
    G-Wiz over 10 years
    bump. what were the results of your tests?
  • G-Wiz
    G-Wiz over 10 years
    Nevermind. Tested myself and ga('send','pageview') after history navigation does not send the updated URL.
  • ChaseMoskal
    ChaseMoskal over 10 years
    @gWiz: I believe I never got the pageview tracking to work, even though I used Google Analytics Debugger (a browser extension) to confirm that my implementation was sending the pageview hit correctly to google.. that were never received. I ended up being extremely frustrated. So I quit and left Google Analytics. Now I just use awstats from cPanel :)
  • Daan Wilmer
    Daan Wilmer almost 9 years
    This does not seem to be an answer to the main question, perhaps it is better suited as a comment to ChaseMoskal's answer.
  • James
    James over 8 years
    +1 for including source reference. It may be a bit harsh to say ga('send', 'page', '/new-page'); is wrong. The source suggests 'send' this but then says you should use 'set' "if you send other hits (e.g. events or social hits)".
  • Geradlus_RU
    Geradlus_RU over 7 years
    Even though I've upvoted this answer, I believe it's a bit out of date and the correct answer is the one written by @Nicolo. At present days documentation suggests to use set command first and then use send, e.g. ga('set', 'page', '/new-page.html'); ga('send', 'pageview');.
  • Geradlus_RU
    Geradlus_RU over 7 years
    This must be an accepted answer (see my earlier comment) until current one is not up to date
  • Dmitri Larionov
    Dmitri Larionov over 6 years
    I believe that this won't help in the scenario where you want to track page fragments aka hash aka everything after #.