The History API (pushState and popstate)
Changes the URL shown in the address bar without a page reload, and handles the browser's back/forward buttons — the mechanism client-side routers are built on.
history.pushState(state, "", path) / window.addEventListener("popstate", handler)
Purpose
history.pushState adds a new entry to the browser’s session history and updates the visible URL,
without triggering a page load. popstate fires when the user navigates via the back/forward
buttons (or history.back()/forward()), letting application code re-render for the new URL.
Syntax
function navigateTo(path) {
history.pushState({}, '', path);
renderPageFor(path);
}
window.addEventListener('popstate', () => {
renderPageFor(location.pathname);
});
Behavior notes
pushStatedoes not trigger navigation, a page load, or apopstateevent on its own — the calling code is entirely responsible for rendering whatever the new URL represents.history.replaceStatebehaves the same way but replaces the current history entry instead of adding a new one — useful for a redirect that shouldn’t itself become a back-button stop.popstateonly fires for browser-initiated navigation (back/forward, or a script callinghistory.back()) — not for a call topushStateitself.- The first argument to
pushState(a state object) is retrievable later viaevent.stateinside thepopstatehandler — useful for restoring view-specific data without a re-fetch.
Common mistakes
- Calling
pushStateand expecting the page to visually update automatically — nothing renders until the application explicitly does so. - Not handling
popstateat all, leaving the back button changing the URL with no corresponding visual change.
Runtime notes
Part of the HTML standard — browser-only.