Web History API
The History API lets a single-page app change the URL and react to back/forward navigation without a full page reload — the foundation of every client-side router.
The classic three methods
| Call | What it does |
|---|---|
history.pushState(state, "", url) | New entry — back button works. |
history.replaceState(state, "", url) | Replace current entry — no new back step. |
history.back() / forward() / go(n) | Move along the stack. |
React to back/forward
JS
window.addEventListener("popstate", (e) => {
render(location.pathname, e.state);
});
function navigate(url, state = {}) {
history.pushState(state, "", url);
render(url, state);
}
state objects
The first argument to pushState / replaceState is any serialisable value — restored as event.state on popstate.
JS
history.pushState({ scrollY: window.scrollY, page: 2 }, "", "/users?page=2");
window.addEventListener("popstate", (e) => {
if (e.state) window.scrollTo(0, e.state.scrollY);
});
The modern Navigation API
Chromium ships a friendlier replacement that handles intercepted clicks, async transitions, and same-document navigations:
JS
navigation.addEventListener("navigate", (e) => {
if (e.canIntercept && !e.hashChange) {
e.intercept({ async handler() {
await loadPage(e.destination.url);
}});
}
});
navigation.navigate("/users?page=2");
Tip: Always serialise small state into
pushState (scroll position, form draft IDs). It survives back/forward and helps the page feel snappy.Example
Example
<!DOCTYPE html>
<html>
<body>
<p id="out"></p>
<script>
document.getElementById("out").textContent = "Hello from Web History API!";
</script>
</body>
</html>
Try it Yourself »
Exercise
Update the URL to /users without a reload.
history.
(null, '', '/users');
Two words concatenated.
Discussion
Loading…