JavaScript — History
The session history
Each tab keeps its own navigation stack:
history.back(); // ← like the Back button
history.forward(); // →
history.go(-2); // jump two entries back
history.length; // how deep this tab's stack is (no URLs exposed!)
Scripts can only manipulate their own tab's session history — reading the user's full browsing history is off-limits by design.
pushState — URL changes without reloads
The foundation of every single-page app:
history.pushState(
{ page: "about" }, // state object (yours to define)
"", // title (mostly ignored)
"/about" // visible URL — same-origin only!
);
location.pathname; // "/about" — but NO network request happened
The state travels with that entry:
history.state; // { page: "about" }
popstate — reacting to Back/Forward
window.addEventListener("popstate", event => {
console.log(event.state); // state of the NEW current entry
render(location.pathname); // re-render for the URL
});
Fires on Back/Forward/go() — not on your own pushState calls (call render yourself there).
pushState vs replaceState
history.pushState(state, "", url); // ADDS a step (Back returns here)
history.replaceState(state, "", url); // OVERWRITES current entry
replaceState suits: fixing a canonical URL after filters change, cleaning tracking params — anywhere Back shouldn't replay a meaningless intermediate state.
Minimal SPA router in ~10 lines
function navigate(path) {
history.pushState({}, "", path);
render(path);
}
window.addEventListener("popstate", () => render(location.pathname));
document.querySelectorAll("a[data-link]").forEach(a =>
a.addEventListener("click", e => {
e.preventDefault();
navigate(a.getAttribute("href"));
})
);
Your app now owns rendering per URL.
Scroll restoration
history.scrollRestoration; // "auto" (browser tries) | "manual"
history.scrollRestoration = "manual"; // you control scroll on navigation
Gotchas
- pushState does NOT fetch anything — you must render the content; servers must also handle direct visits to SPA routes
- Same-origin URLs only — it's not a redirect tool
- State objects are serialized (structured clone) — functions need not apply
Mini Practice
- Walk back/forward programmatically; log history.length at each stop.
- pushState three routes with distinct state objects.
- Render different content per route via popstate + pathname.
- Use replaceState to strip a
?ref=spamparameter. - Set scrollRestoration manual; observe Back behavior change.
Next: navigator →
Related Topics
Frequently Asked Questions about History
What is History in JavaScript?
History is a fundamental concept in JavaScript. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn History?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn History.
Why is History important in JavaScript?
History is essential for JavaScript development. Understanding this concept will help you write better code and solve real-world problems more effectively.