Modifying browser history with Javascript

We lost the browser state when we replaced our Charts UI w/AJAX manipulation. While it’s possible to maintain state using an anchor ala Gmail (ie – gmail.com/mail?#inbox/THREAD), it breaks the separation between business and view logic. The server cannot access the state information contained in the anchor – it’s only accessible from the browser.

To maintain state, we’d need a combination of Javascript parsing and additional requests to retrieve chart data. Our views would be a confusing mess of logic. I’m glad we punted – we can maintain state in 3 lines of Javascript now.

pushState() and replaceState()

Modern browsers now allow you to modify the browser history via Javascript. Here’s an example, shamelessly lifted from Mozilla:

Suppose http://mozilla.org/foo.html executes the following JavaScript:

var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");

This will cause the URL bar to display http://mozilla.org/bar.html, but won’t cause the browser to load bar.html or even check that bar.html exists.

We’re using replaceState(), which modifies the current history item. It doesn’t create a new one. Why not pushState()?

The implementation

It’s a beautiful three-liner considering past alternatives:

if (typeof window.history.pushState == 'function') {
  history.replaceState({}, 'Scout ~ Chart', '/charts?'+Chart.params());
}

Wrapup

These window.history functions are supported in Firefox 4, Chrome 6, Safari 5, and Mobile Safari on iOS 4+.

A big thanks goes out to Rails Machine CTO Jesse Newland (and his gorgeous mane of hair) for the suggestion.