Modifying browser history with Javascript

December 07 Bullet_white By Derek Bullet_white Posted in Development Bullet_white Comments Comments

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()?

  • replaceState() meets our needs: sharing the location in the URL bar and refreshing the page should reflect the current state of the chart.
  • We didn’t want small chart tweaks to pollute the browser history.
  • pushState() would still require business logic in our views to support the back button. While it’s easier to access the data through the stateObj than parsing from the anchor tag, it’s not worth the complexity in our case.

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.

Get notified of new posts.

Once a month, we'll deliver a finely-curated selection of optimization tips to your inbox.

Comments

comments powered by Disqus