Browser back button and AJAX

You created AJAX based website and your client asks why Back button does not work? How is it possible that in Gmail inbox she/he can read emails, write a new email, check spam and send emails without leaving the page and still can get back by using Back button?

If you try to google for the solution you will be offered with bunch of out-of-the-box cross-browser JavaScript tools that do the job but you need to spend couple of days to read the documentation, integrate it and of course pay for it. Good news are that you don’t have to use these – the solution is very simple.

The first idea that might come to your mind is to:

  • save all actions with parameters in some global stack object
  • detect when an user clicks on Back button
  • go through this stack of actions

But your stack is just one JavaScript object and if you refresh a page, it will be lost and we don’t want that. We want to have complete history of actions when user leaves the page and come back for any reason. To do this, we can manipulate a browser history.

How to push new history state upon user’s action?

var stateObj = {myAction:'whatIDid', params : {myParam:1, myParam2:'x'} };
window.history.pushState(stateObj, '', '#thisWillBeAddedToUrl');

In stateObj you can put any properties you want. This is just an example.

How to detect user’s click on Back and Forward buttons and fetch the state?

$(function() {
if (window.history && window.history.pushState) {
$(window).on('popstate', function() {
var stateObj = window.history.state;
doSomethingWithThisState(stateObj);
});
}
});

When an user leaves the page and comes back, how to recover the state of the page that we had just before the user left that page?

$(document).ready(function(){
var stateObj = window.history.state;
doSomethingWithThisState(stateObj)
});

Here is the full example where an user can change CSS properties of some text and can go through these changes by clicking back and forward. When you refresh the page, the colors will still be there.

Off course, in the real world where you need Back button support for AJAX based page, you will save URLs called by AJAX instead of these CSS properties. The thing is, you can put there anything you want.

This is another example where this solution is used by the creator of this post.

Apart from history.pushState() there is also history.replaceState() which modifies the current history entry instead of creating a new one. This is useful for actions that are not important enough for the whole new history state but again influences it on some way eg. user changes the search property but does not change the search term.