Good tutorial for using HTML5 History API (Pushstate?)

JavascriptHtmlPushstateHtml5 History

Javascript Problem Overview


I am looking into using the HTML5 History API to resolve deep linking problems with AJAX loaded content, but I am struggling to get off the ground. Does any one know of any good resources?

I want to use this as it seems a great way to allow to the possibility of those being sent the links may not have JS turned on. Many solutions fail when someone with JS sends a link to someone without.

My initial research seems to point to a History API within JS, and the pushState method.

http://html5demos.com/history

Javascript Solutions


Solution 1 - Javascript

For a great tutorial the Mozilla Developer Network page on this functionality is all you'll need: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history

Unfortunately, the HTML5 History API is implemented differently in all the HTML5 browsers (making it inconsistent and buggy) and has no fallback for HTML4 browsers. Fortunately, History.js provides cross-compatibility for the HTML5 browsers (ensuring all the HTML5 browsers work as expected) and optionally provides a hash-fallback for HTML4 browsers (including maintained support for data, titles, pushState and replaceState functionality).

You can read more about History.js here: https://github.com/browserstate/history.js

For an article about Hashbangs VS Hashes VS HTML5 History API, see here: https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling

Solution 2 - Javascript

I benefited a lot from 'Dive into HTML 5'. The explanation and demo are easier and to the point. History chapter - http://diveintohtml5.info/history.html and history demo - http://diveintohtml5.info/examples/history/fer.html

Solution 3 - Javascript

Keep in mind while using HTML5 pushstate if a user copies or bookmarks a deep link and visits it again, then that will be a direct server hit which will 404 so you need to be ready for it and even a pushstate js library won't help you. The easiest solution is to add a rewrite rule to your Nginx or Apache server like so:

Apache (in your vhost if you're using one):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
 </IfModule>

Nginx

> rewrite ^(.+)$ /index.html last;

Solution 4 - Javascript

The HTML5 history spec is quirky.

history.pushState() doesn't dispatch a popstate event or load a new page by itself. It was only meant to push state into history. This is an "undo" feature for single page applications. You have to manually dispatch a popstate event or use history.go() to navigate to the new state. The idea is that a router can listen to popstate events and do the navigation for you.

Some things to note:

  • history.pushState() and history.replaceState() don't dispatch popstate events.
  • history.back(), history.forward(), and the browser's back and forward buttons do dispatch popstate events.
  • history.go() and history.go(0) do a full page reload and don't dispatch popstate events.
  • history.go(-1) (back 1 page) and history.go(1) (forward 1 page) do dispatch popstate events.

You can use the history API like this to push a new state AND dispatch a popstate event.

history.pushState({message:'New State!'}, 'New Title', '/link');
window.dispatchEvent(new PopStateEvent('popstate', {
  bubbles: false,
  cancelable: false,
  state: history.state
}));

Then listen for popstate events with a router.

Solution 5 - Javascript

You could try Davis.js, it gives you routing in your JavaScript using pushState when available and without JavaScript it allows your server side code to handle the requests.

Solution 6 - Javascript

Here is a great screen-cast on the topic by Ryan Bates of railscasts. At the end he simply disables the ajax functionality if the history.pushState method is not available:

http://railscasts.com/episodes/246-ajax-history-state

Solution 7 - Javascript

I've written a very simple router abstraction on top of History.js, called StateRouter.js. It's in very early stages of development, but I am using it as the routing solution in a single-page application I'm writing. Like you, I found History.js very hard to grasp, especially as I'm quite new to JavaScript, until I understood that you really need (or should have) a routing abstraction on top of it, as it solves a low-level problem.

This simple example code should demonstrate how it's used:

var router = new staterouter.Router();
// Configure routes
router
  .route('/', getHome)
  .route('/persons', getPersons)
  .route('/persons/:id', getPerson);
// Perform routing of the current state
router.perform();

Here's a little fiddle I've concocted in order to demonstrate its usage.

Solution 8 - Javascript

You may want to take a look at this jQuery plugin. They have lots of examples on their site. http://www.asual.com/jquery/address/

Solution 9 - Javascript

if jQuery is available, you could use jQuery BBQ

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMild FuzzView Question on Stackoverflow
Solution 1 - JavascriptbaluptonView Answer on Stackoverflow
Solution 2 - JavascriptKiran AghorView Answer on Stackoverflow
Solution 3 - JavascriptMauvis LedfordView Answer on Stackoverflow
Solution 4 - JavascriptErik RingsmuthView Answer on Stackoverflow
Solution 5 - JavascriptOliver NightingaleView Answer on Stackoverflow
Solution 6 - JavascriptdebView Answer on Stackoverflow
Solution 7 - Javascriptaknuds1View Answer on Stackoverflow
Solution 8 - JavascriptNate TottenView Answer on Stackoverflow
Solution 9 - JavascriptsprugmanView Answer on Stackoverflow