Skip to main content

Listen for the popstate event to see when the user clicks the “back” button

More generally, it fires whenever the user is navigating the session history.

I was writing a web page and I needed to take some action when the user clicked the “back” button in their browser. I discovered the popstate event, which fires on precisely this event – and more generally, whenever the user navigates the session.

This is an app where I was storing all the state in the URL query string, so the back button was changing the state of the app.

Here’s a simple demo I wrote, which is a counter that stores state in the query string, and works if I click the back/forward buttons:

???

    Here’s the source code:

    <p>
      <div id="value">???</div>
      <button onclick="increment();">+</button>
      <button onclick="decrement();">&minus;</button>
    </p>
    
    <ul id="events"></ul>
    
    <script>
      function recordEvent(message) {
        document.querySelector("#events").innerHTML +=
          `<li>${message}</li>`;
      }
    
      function setValue(value, { updateUrl }) {
        const url = new URL(window.location);
        const params = new URLSearchParams(url.search);
    
        document.querySelector("#value").innerText = value;
    
        if (updateUrl) {
          params.set('value', value);
    
          url.search = params.toString();
    
          history.pushState(
            {},
            "", // unused
            url.toString()
          );
        }
      }
    
      function getValue() {
        const params = new URLSearchParams(window.location.search);
        const value = Number(params.get("value") || "0");
    
        return value;
      }
    
      window.addEventListener("DOMContentLoaded", function() {
        const value = getValue();
        setValue(value, { updateUrl: true });
        recordEvent(`loaded page and set initial value as ${value}`);
      });
    
      function increment() {
        const value = getValue();
        setValue(value + 1, { updateUrl: true });
        recordEvent(`called increment() to set value to ${value + 1}`);
      }
    
      function decrement() {
        const value = getValue();
        setValue(value - 1, { updateUrl: true });
        recordEvent(`called decrement() to set value to ${value - 1}`);
      }
    
      window.addEventListener("popstate", function() {
        const value = getValue();
        setValue(value, { updateUrl: false });
        recordEvent(`calling the popstate event handler to set the value to ${value}`);
      });
    </script>