Browser history with pushState()

When developing a Single Page Application (SPA) or any other app for that matter, you'll probably want to use this magic goodness called: pushState()

This method allows us to modify and manipulate the browser's history. From simulating an anchor effect to changing the whole URL should you need it.

In the case above I'll use it to change the URL every time you switch tabs within the web app. We'll modify the URL from whatever.html to whatever.html#content-1 depending on the user click.
If you think about it that's an awesome feature for the user, he can keep this URL whatever.html#content-1 to access the desired tab directly.

The HTML

Super straight forward HTML, some data attributes in the buttons and the containers hidden by default using CSS.

<div class="tabs">
  <span data-content="content-1">Tab 1</span>
  <span data-content="content-2">Tab 2</span>
  <span data-content="content-3">Tab 3</span>
</div>

<div id="content-1" class="content">
  This is the content 1
</div>
<div id="content-2" class="content">
  This is the content 2
</div>
<div id="content-3" class="content">
  This is the content 3
</div>

The JavaScript

For the JavaScript I'll use jQuery for a simpler DOM manipulation.

The pushState() method accepts three parameters:

  • state object: in our simple example we'll pass an empty object. Refer here for more information about it.
  • title: some browsers ignores this parameter, I always set it, it can't hurt.
  • URL: the new value for the URL.
$(document).ready(function () {
  $(".tabs span").on("click", function (event) {
    // Hide all the containers
    $('.content').hide();

    // Get the data attribute from the button
    var container = $(this).data('content');

    // Show the selected container
    $('#' + container).show();

    // Use Pushstate to change the URL
    var stateObj = {};

    // Check if browser supports PushState
    if (history.pushState) {
      history.pushState(stateObj, container, "#" + container);
    }
  });
});

Demo

View Demo

Learn more about Manipulating the browser history.

About Rick

Senior Front-end Software Engineer from Barcelona, Haidong Gumdo Instructor (korean martial art of the sword), street photographer, travel lover, TV addict, Boston Red Sox fan, and privacy advocate.
2 comments
  • Hi Rick,

    Thanks for the nice code snippet. I am trying to modify it for my own needs, simple AJAX loading of a few pages with pushHistory and popstate.

    Everything is working fine, but the problem is with popstate. If I load a page with AJAX, it loads as expected, and the back button works(popstate).

    Then if I open that same page with the same link, and try to go back, I need to click back two times. If I open it again, then it is backX3, and so on.

    Here is my code. Any help is appreciated.

    
    $(function(){
        var $main = $('#main');
        var stateObj = {};
    
        $(window).on('popstate', function (e) {
            loadPage(location.pathname); 
        });
    
        $(document).on('click', 'a', function(){
            var href = $(this).attr('href');
            history.pushState(stateObj, '', href);
            loadPage(href);
            return false;
        })
    
        loadPage = function(href){
            $main.load(href);
        }
    })
    

Leave a Reply

Add <code> Some Code </code> by using this tags.

*
*