Congratulations! You just made a single page web application [SPWA] to do All The Things. What happens when you hit the Back button in the browser? Oops.
The Back button is the most used navigation button in the modern browser. SPWA often break the functionality of the Back button. We can fix this using the HTML 5 History API.
For this demo, I’ll make a simple web page starting with the text “Page 1” and a “Continue” button. When I click the “Continue” button, “Welcome” will change to “Page 1”; when I click “Page 1”, I change to “Page 2”; ad infinitum. My initial page looks like this:
1 2 3 4
1 2 3 4 5 6 7 8 9 10 11 12 13
Running this code and clicking “Continue”, the user has no way to go back. He or she would need to start over from the beginning, which is bad for the user and bad for us too. We can update the browser’s history using
popState commands from the History API. For this contrived example, I’ll add my
pushState call in the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Now the site will add
?page= to the URL whenever we update the page number. This happens when we call
history.pushState. In the call to
history.pushState, the first argument is some data identifying the state, the second argument is the
title of the new page but is currently unused by all the major browsers, and the third argument is the URL of the new state.
In doing this, the Back button has become enabled in the browser. However, it still doesn’t work. That’s where
popState comes in.
popState is the other side of the equation which figures out how to change the page when the user hits the Back button. I’ll update the call to
pushState to include the page number in the
state arugment so we can use it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Now your history should be mostly working. Hitting Back should take you to the previous page, then hitting Forward should take you to the next page.
There is currently a bug in the version of webkit Safari uses which causes a
popstate event to fire on initial page load. We can try to fix this using the
1 2 3 4 5 6 7
Of course, I want my web page to be smarter than this. If the user explicitly visits “mysweetpage.com?page=3” I want the user to be presented with page 3’s epic content. Let’s modify that
onload function to check the current URL state and figure out which page the user has visited:
1 2 3 4 5 6 7 8 9
History changed. Forever. Changing history is a good idea but can easily lead to an even more confusing user scenario. Choose when to change history based on when your application would traditionally need to bring up a new page. Once you have Back working, make sure Forward also acts as expected. Thinking about how you’ll integrate the History API into your web application can help you write more sensible, modular code.
If you’re looking for the full code that we created above, check out this gist.