React Forum
Blog & Guide Responses
Mar 25, 2023 · 04:00 AM

MDN History API - discussion (2023-03-25)

Started by Lena Fischer
externalhistory apiroutingpushStatereplaceStatepopstatenavigationstate restorationevidence

The History API docs are one of those references you only appreciate after you've debugged a back/forward bug in production. It's not just about pushState—it's about deciding what state belongs in the URL, what belongs in history state, and how to restore posture without surprises.

Read the MDN docs

Do you use history.state for UI posture (panel/tab/selection), or do you keep posture purely in the URL? How do you handle popstate restoration without re-running expensive work or re-triggering effects incorrectly? Do you log navigation transitions (push/replace/pop) as tips lines so back/forward bugs are explainable?

Comments (16)

Back to latest
Jun Park
Mar 29, 2023 · 09:09 AM

URL for shareable posture, history state for ephemeral posture.

Otherwise you end up encoding the whole app in query params.

Rafael Soto
Apr 02, 2023 · 02:02 AM

We started logging history transitions and it paid off immediately:

txt
[tips] nav push path=/search?tag=hooks reason=userClick
[tips] nav replace path=/search?tag=hooks&page=2 reason=pagination
[tips] nav pop path=/search?tag=hooks reason=backButton restore=historyState

Before that, back/forward bugs were basically ghost stories.

Grace McCoy
Apr 10, 2023 · 10:10 AM

Docs tie-in: the routing docs are basically a policy layer on top of History semantics.

Related: Routing and Navigation and Core Concepts.

Mei Tan
Apr 17, 2023 · 04:16 PM

Concrete alternative: keep everything in URL, never use history.state.

We tried that. It worked until we needed to restore scroll + selection without polluting share links. History state is fine if you treat it as a contract with evidence.

Lena Fischer
Apr 19, 2023 · 12:12 PM

Yeah, I think the guardrail is: if it changes what someone expects from a link, it belongs in the URL.

If it's about restoration after a user action (scroll/selection), history state is a better fit.

Nina Kapoor
May 06, 2023 · 06:06 AM

Long-form: popstate restoration is where apps accidentally become non-idempotent.

If your route-enter logic kicks off fetches, effects, analytics, etc., then back/forward can double-trigger behavior. We had to make route enter replay-safe and log when we were replaying vs doing fresh work.

That is less about History itself and more about having a posture model that can be restored without side effects.

Caleb Price
May 22, 2023 · 10:22 PM

We only use replaceState for normalization (canonicalizing URLs) and never for user navigation.

Otherwise back/forward gets confusing because users can't return to what they just did.

Sofia Martinez
Jun 18, 2023 · 06:18 PM

We store scroll restoration in history state and treat it like a hint, not a guarantee.

If content identity changed, we log a fallback reason and don't pretend the scroll is exact.

Ibrahim Saleh
Jul 07, 2023 · 07:07 AM

A practical policy that worked for us:

txt
[tips] historyState allowedKeys=[scroll,selection] disallow=[filters,auth]

It forces you to decide what is restoration-only vs shareable posture.

Lina Ortega
Aug 21, 2023 · 09:21 PM

Short take: if back/forward is buggy, your route-enter work is not replay-safe.

Evan Brooks
Sep 12, 2023 · 12:12 PM

We found it helpful to render a small evidence token like nav:pop on the shell in dev builds.

It stops you from misattributing bugs to "random state" when it was actually a popstate restore path.

Arman Qadir
Oct 18, 2023 · 06:18 PM

Long-form counterpoint: History state can become a hidden global store if you abuse it.

If teams start stuffing random objects in history.state, you lose the whole point of explicit contracts. Keep it tiny and log writes.

Tomas Rivera
Nov 10, 2023 · 10:10 AM

We standardized navigation transitions as actions: navPush, navReplace, navPopRestore.

Even if under the hood it's History API, naming it as actions kept it reviewable.

Anika Sharma
Dec 05, 2023 · 05:05 AM

We added a tiny helper that prints a one-line tips log whenever we write to history.

It prevented accidental replaceState loops where the URL kept changing.

Marisol Vega
Dec 18, 2023 · 06:00 PM

If you canonicalize URLs, do it once and make it converge.

If parse/serialize doesn't converge quickly, you built a navigation oscillator.

Salma Qureshi
Dec 29, 2023 · 09:09 AM

We treat history.state as the place for restoration hints only.

If it affects product behavior in a share link, it belongs in the URL.

Priya Liao
Dec 31, 2023 · 11:10 PM

Takeaway: the History API is simple; the policy decisions are not.

Write the policy down, log transitions, and back/forward stops being a mystery.