Skip to content
tezvyn:

Manipulate Browser History with pushState and replaceState

Source: developer.mozilla.orgEasyHow cards are made

Manipulate Browser History with pushState and replaceState

Make a single-page app feel like a multi-page site. pushState changes the URL without a full page reload, creating a new browser history entry. This is essential for SPAs to enable shareable links and a working back button.

Why it exists

Traditional websites reload the entire page on every click, which is inefficient and loses application state. Single-Page Applications (SPAs) solve this by updating the page with JavaScript, but this breaks the user's expectation that the URL and back/forward buttons will work. The History API was created to bridge this gap.

The mental model

Think of pushState as manually adding a fake entry to the browser's history log. You're telling the browser, "We didn't actually load a new page from the server, but please change the URL in the address bar and remember this state. If the user hits 'back', let me know so I can handle it."

How it works

In an SPA, when a user clicks a link, your JavaScript code prevents the default page load. It then fetches the necessary data, updates the page content, and calls history.pushState(stateObject, "", "/new-url"). This changes the URL in the address bar and adds an entry to the session history without a network request for a new page. replaceState works similarly but modifies the current history entry instead of adding a new one. When the user navigates with the back or forward buttons, the browser fires a popstate event, which your app must listen for to render the correct view for that history entry.

When to use it

Use this API in Single-Page Applications (React, Vue, Angular, etc.) to create a seamless user experience. It's essential for implementing client-side routing, enabling deep linking (sharing a URL to a specific view), and making the browser's back and forward buttons behave as expected.

When not to use it

Avoid this API in traditional multi-page websites where each URL corresponds to a distinct HTML file served from a server; the browser handles history automatically in that case. Critically, do not use pushState if you are not prepared to also implement a listener for the popstate event, as this will break the back button.

One canonical example

A user is viewing a product list at myspa.com/items. They click a category filter for "shoes". The app prevents a page reload, fetches the filtered items, updates the list in the DOM, and calls history.pushState({}, "", "/items?category=shoes"). The URL updates. If the user then clicks the back button, a popstate event fires, and the app's router must detect the old URL (/items) and re-render the original, unfiltered list.

Interview question

What is the primary issue if an SPA uses history.pushState() but fails to implement a popstate event listener?

  • a.The pushState call itself will fail, preventing the URL from ever changing.
  • b.The browser will automatically perform a full page reload when the user clicks the back button.
  • c.The application's content will not update to reflect the correct state when the user navigates using browser history buttons.Correct
  • d.The URL will update, but the browser's back and forward buttons will not change the URL.
Why?

The card states that failing to implement a popstate listener will 'break the back button,' meaning the application won't react to history navigation by rendering the correct content. The browser does not automatically reload the page; it fires the popstate event, expecting the SPA to handle the UI update.

Just read this? Test yourself on what you have been reading.

Read the original → developer.mozilla.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on web apis — each one lists the topics its interview covers.

See open roles