A Quick guide about popstate event in JavaScript, If you’ve ever hit the back button in your browser and wondered how your Single-Page Application knows which view to render, this guide is for you.
Vijay Sai Krishna vsuri
Last Updated Aug 21, 2025
popstate
in Single Page Applications (SPAs)We'll demystify the popstate
event, explore examples in vanilla JavaScript, and then compare how libraries like React Router handle it under the hood.
popstate
in JavaScript?The popstate
event is fired on the window
whenever the active history entry changes. This usually happens when the user clicks Back or Forward in the browser
window.addEventListener("popstate", (event) => {
console.log("Location changed to:", window.location.pathname);
console.log("State object:", event.state);
});
Important notes:
hashchange
, popstate
deals with the History API (pushState
, replaceState
, back
, forward
, go
).pushState
or replaceState
directly.history.back()
, history.forward()
, etc.Imagine a single-page app with two pages:
<button id="page1">Go to Page 1</button>
<button id="page2">Go to Page 2</button>
<div id="content"></div>
const content = document.getElementById("content");
function renderPage(page) {
content.textContent = `You are on ${page}`;
}
document.getElementById("page1").onclick = () => {
history.pushState({ page: "Page 1" }, "", "/page1");
renderPage("Page 1");
};
document.getElementById("page2").onclick = () => {
history.pushState({ page: "Page 2" }, "", "/page2");
renderPage("Page 2");
};
window.addEventListener("popstate", (event) => {
if (event.state) {
renderPage(event.state.page);
}
});
postMessage
for syncing history between origins.pushState
/replaceState
don’t trigger popstate
.To synchronize navigation across iframes, use a communication layer with postMessage
.
Question:
👉 "If I open /page2
directly in the browser, how does my SPA know what to render?"
/page2.html
index.html
(History API Fallback)index.html
loads:window.location.pathname
<BrowserRouter>
<Routes>
<Route path="/page1" element={<Page1 />} />
<Route path="/page2" element={<Page2 />} />
</Routes>
</BrowserRouter>
Opening /page2
loads index.html
, then React Router handles the routing.
❌ If the server isn’t configured: You’ll get a 404 error, since the server looks for /page2/index.html
and doesn’t find it.
✅ Solution: Configure the server to always return index.html
.
React Router (v6 and above) leverages the History API just like your vanilla JS examples, but with abstraction:
<Link>
and hooks like useNavigate()
popstate
and re-renders the correct component treeimport { BrowserRouter, Routes, Route, Link } from "react-router-dom";
export default function App() {
return (
<BrowserRouter>
<nav>
<Link to="/page1">Page 1</Link>
<Link to="/page2">Page 2</Link>
</nav>
<Routes>
<Route path="/page1" element={<div>You are on Page 1</div>} />
<Route path="/page2" element={<div>You are on Page 2</div>} />
</Routes>
</BrowserRouter>
);
}
React Router saves you from writing boilerplate like:
popstate
location.pathname
popstate
is triggered on browser history navigation, not on pushState
/replaceState
popstate
is scoped to the iframe/windowindex.html
(History API fallback)window.location.pathname
Advertisement
Advertisement
Alok Kumar Giri
Last Updated Jun 2, 2025
Code snippet examples which will help to grasp the concept of Hoisting in JavaScript, with solutions to understand how it works behind the scene.
Anuj Sharma
Last Updated Oct 2, 2025
Explore Polyfill for map, filter and reduce array methods in JavaScript. A detailed explanation of Map, filter and reduce polyfills in JS helps you to know the internal working of these array methods.
Anuj Sharma
Last Updated Aug 3, 2025
Explore the implementation of setTimeout in JavaScript with a detailed explanation for every step. Understand all scenarios expected to implement the setTimeout polyfill.
Frontendgeek
Last Updated Sep 25, 2025
Understand the JWT(JSON Web Token) and how JWT decode works. It also covers how the end-to-end JWT authentication works between client & server, along with the pros and cons of using JWT.
Anuj Sharma
Last Updated Oct 4, 2025
Understand polyfill for Async Await in JavaScript with a step-by-step explanation. This helps in understanding the internal functioning of Async Await in JavaScript.
Anuj Sharma
Last Updated Sep 14, 2025
Learn hoisting in JavaScript with clear examples and explanations. Understand variable hoisting in JavaScript, function hoisting in JavaScript, and how the temporal dead zone affects hoisting in JS.
Subscribe to FrontendGeek Hub for the frontend interview preparation, interview experiences, curated resources and roadmaps.
© 2024 FrontendGeek. All rights reserved