Skip to content
tezvyn:

SPA back button: what event fires and how do you handle it?

Source: developer.mozilla.orgMediumHow cards are made

SPA back button: what event fires and how do you handle it?

Tests History API literacy. Strong answer: popstate event, PopStateEvent type, restore UI via event.state, and zero-delay setTimeout for DOM sync. Red flag: confusing popstate with pushState or using hashchange for modern History API routing.

What's really being asked

This question probes whether you understand the browser's session history mechanics beyond surface-level routing. Interviewers want to see that you know popstate is the event fired when the active history entry changes, that you can type it correctly in TypeScript, and that you are aware of the timing mismatch between window.location and document readiness. It also checks if you know how to reconstruct UI state from the state object carried by the event.

The full answer

First, name the popstate event on the window object and note that it is a PopStateEvent. Second, show a typed listener using window.addEventListener with the handler argument typed as PopStateEvent. Third, explain that event.state holds the copy of the object previously passed to history.pushState or history.replaceState, and you use that payload to restore the previous view. Fourth, guard against null because event.state can be null when the history entry has no state object. Fifth, mention the zero-delay setTimeout quirk from MDN: if you need to act after the document is fully ready, wrap your handler logic in setTimeout with a zero delay because window.location may already reflect the new URL while the document is still catching up. This shows you have dealt with real browser timing in production.

The mistakes people make

A major red flag is claiming that history.pushState or history.replaceState trigger popstate; they do not. Another is suggesting hashchange as the primary handler for a modern pushState-based SPA, which confuses two different routing paradigms. Candidates also stumble by forgetting to type the event as PopStateEvent, or by ignoring the null state case, which leads to runtime errors when the user navigates to an entry that was never pushed with a state object.

What usually comes next

The interviewer may ask how you would restore scroll position across history entries, or how you would handle deep links that land on a route without a corresponding history state object. They might also ask how to prevent memory leaks when adding the listener in a framework lifecycle, or how server-side rendering interacts with client-side history restoration.

A concrete example

Suppose a photo gallery SPA calls history.pushState with a state object containing photoId 42 and the URL /photos/42 when opening an image. When the user clicks back, the browser fires popstate and event.state equals that object. Your listener reads that ID, fetches metadata if needed, and re-renders the gallery overlay. If you instead need to measure DOM nodes immediately, you defer work with setTimeout so the browser finishes its internal document updates first. Without that deferral, you might read stale layout metrics.

Interview question

In a pushState-based SPA, the user clicks the browser back button. Which approach correctly restores the previous view?

  • a.Listen for pushstate on window and read event.state to restore the view immediately.
  • b.Listen for hashchange on window and read history.state to restore the view synchronously.
  • c.Listen for popstate on window, guard event.state against null, and defer DOM work with setTimeout(..., 0).Correct
  • d.Listen for popstate on window and call history.pushState to recreate the previous history entry.
Why?

popstate fires when the active history entry changes, carrying the state object in event.state which may be null, and a zero-delay setTimeout ensures the DOM has caught up before reading layout. Option D is tempting because it names the right event, but calling pushState inside the handler creates a new history entry rather than restoring the existing one.

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 typescript — each one lists the topics its interview covers.

See open roles