Proposal: history-aware links — go back instead of pushing for "Back to X" links (preferBack) #7699
KurtGokhan
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
I'd like to propose a built-in way for
Linkto be history-aware: a "Back to X" link should return to the entry the user came from when that entry is X — using the browser's back behavior — instead of always pushing a brand-new history entry. I'm imagining this as apreferBackprop onLink(plus a small hook primitive for custom links), and I'd love feedback on whether this belongs in the router and what the API should look like.The problem
"Back to X" is one of the most common navigation patterns there is — "Back to issues", "Back to results", "← Posts". Today the idiomatic way to build it is a normal link:
The catch: this always pushes a new history entry, even when
/issuesis exactly the entry the user just came from (/issues→/issues/42→ "Back to issues"). That has two real costs:/issuesentry; the browser's forward button no longer returns them to/issues/42./issuesentry — so the user loses their place in a long list.A genuine "back" would fix both, but you can't unconditionally call
history.back()for a "Back to X" link: if the user arrived some other way (deep link, refresh, came from a different page), back would take them somewhere unexpected — or right out of the app. So the behavior has to be conditional: go back if and only if the link's target is the previous entry; otherwise navigate normally.That decision is genuinely hard to make in userland, because the browser only ever exposes the current history entry — there's no API to ask "what was the previous entry?". Answering that reliably is something the router is uniquely positioned to do, which is why this feels like it belongs in TanStack Router rather than in every app's snippets folder.
What I'm proposing
A
preferBackprop on the existingLink:Behavior (what it does, not how):
replace).<a href>, so keyboard navigation, "copy link address", and middle/modifier-click (open in new tab) all keep working as users expect.For links that aren't a
Link(custom buttons, design-system components), the same decision would be available as a small hook so the behavior can be reused.Benefits
history.back()plumbing, no guessing.Linkoptions and stays opt-in — zero impact on existing links.Link.Prior art / motivation
Frameworks and browsers already invest heavily in preserving back/forward semantics and per-entry scroll restoration; this proposal is about letting declarative "Back to X" links participate in that instead of fighting it. Because only the router has the context to know whether a target is the previous entry, a first-class option avoids every app re-implementing (and getting subtly wrong) the same conditional-back logic.
Open questions
Linkas a prop, or would you prefer it live only as a hook / a helper?preferBackis meant to signal the best-effort semantics (it prefers back, falling back to a push). Open to alternatives.replace, or keep that out of scope?Status
I have a working prototype at #7700 (behavior + tests + docs) and would be happy to improve on it if the direction looks good. Scoped to React first; the underlying mechanism is framework-agnostic, so Solid/Vue parity would be a natural follow-up. Wanted to align on the what and why here.
Here is an example showing that how a Link with
preferBacksynergyzes with scroll restoration.Google.Chrome-Vite.App-000783.mp4
Beta Was this translation helpful? Give feedback.
All reactions