URIs for dynamic pages.

Last Update

10/25/2002; 8:43:50 PM

The problem

There's one thing the web gurus agree on. It's axiom 0 in Tim Berners-Lee's web architecture: "Any resource of significance should be given a URI." There are all kinds of good theoretical reasons. And in the practice of the browsable web there are 2 good reasons: What has a URL can be bookmarked and linked to.

One area where this has been problematic is dynamic webpages. These pages load once, and then provide navigation through scripting. If the page needs extra data it is also loaded with scripting. All the time the url doesn't change, so when you bookmark the page, or link to it, it will always show up in its initial state.

Some pages try to solve this by providing a link to the current state, f.e. youngpup.net. This does work, but it requires action from the user. But as dynamic pages are still quite rare, the user will probably find it hard to understand the problem and will not understand why bookmarking doesn't work. For a good user experience the URL in the location bar just has to change automatically.

The problem with changing the url is that the browser will unload the current page and do a new http request. Which is exactly what you don't want with dynamic pages. But there's one exception, which we found out when we were researching this problem at Q42.

The solution

It turns that browsers don't leave the page when you only change the fragment identifier. A fragment identifier is the part of the URI after the '#' sign and they are used to scroll to a specific point on the page. But when there's no anchor with the name of the fragment id, the browser will simply do nothing.

The code

An additional advantage of this method is that the code is really simple. The following function will change the fragment identifier:

function saveStateInURL(state) {

Now that we can change the URL, there has to be script that gets the fragment identifier when the URL has one. Here's the code that does that:

function loadStateFromURL() {
	var hash=location.hash;
	return hash?hash.substr(1):'';

What actually is used as state depends on the page. For the OPML loader I simply used the URL for the loaded OPML file. But you can store anything, as long as it can be serialized to a reasonably sized string.