React Forum
Blog & Guide Responses
Jan 05, 2023 · 04:00 AM

MDN History API - discussion (2023-01-05)

Started by Noah Vance
externalmdnhistorynavigationurlsrouting

MDN's History API docs are a good refresher for what browsers actually provide under every router abstraction.

Read the docs

If you're building custom navigation behavior (modals as routes, stacked panels), how often do you touch history directly? Do you treat history state as part of your route contract, or do you keep it as an internal implementation detail? What's your strategy for keeping back/forward behavior predictable when the UI has internal 'modes'?

Comments (10)

Back to latest
Maya Henson
Jan 05, 2023 · 04:06 AM

We only touch history directly when we need something truly custom (like stacked overlays).

Otherwise we keep it behind routing primitives so it doesn't leak everywhere.

Dmitri Kline
Jan 05, 2023 · 04:14 AM

Back/forward gets weird when internal modes don't show up in the URL. If the mode matters, it should be part of the navigation story somehow.

Related: Routing and Navigation.

Keira Santos
Jan 05, 2023 · 04:22 AM

History state as contract is useful for debugging. If a bug report includes a history state snapshot, you can replay weird flows.

But if you store huge objects, you'll regret it.

Avery Chen
Jan 05, 2023 · 04:33 AM

Predictability rule: if the user can see it, back should undo it. If they can't see it, back shouldn't care.

It sounds obvious, but it forces you to be honest about what 'mode' means.

Salma Qureshi
Jan 05, 2023 · 04:46 AM

We touched history directly for one thing: stacked overlays that needed real back/forward semantics.

ts
history.pushState({ overlay: 'filters' }, '', '?overlay=filters');
window.addEventListener('popstate', (e) => {
  // reconcile overlay mode from e.state / location.search
});

Once we did that, we had to treat overlay mode as a contract, not just UI state.

Keira Santos
Jan 05, 2023 · 04:58 AM

Counterpoint: direct history work is where bugs go to hide.

If you're going to do it, I would keep it behind one routing primitive and render a marker when it is active.

Noah Vance
Jan 05, 2023 · 05:03 AM

Yep. We ended up with a single useHistoryBridge() and a route-visible flag so support could tell when the bridge was involved.

Otherwise the bug reports are impossible to reason about because back/forward behavior depends on hidden state.

Hana Saito
Jan 05, 2023 · 05:16 AM

What helped us: decide what counts as "navigation" and encode it in the URL, even if it's just a small query key.

Once we stopped pretending internal modes were not navigation, back/forward became much less surprising.

Priya Liao
Jan 05, 2023 · 05:28 AM

A tiny pattern that kept things predictable: keep history state small and serializable.

We store only a couple of keys (overlay, step, scrollHint), and everything else is derived from the URL + route doc.

Benji Rios
Jan 05, 2023 · 05:41 AM

A misunderstanding I see: people think history state is a convenient store for random objects.

If you treat it as a contract surface, you naturally keep it small and make the UI reproducible.

Mina Calder
Jan 05, 2023 · 05:55 AM

If you adopt the forum docs posture, the goal is: a screenshot + URL + (maybe) a tiny history state payload should explain the whole navigation story.

Anything beyond that tends to rot.