fw-08 — Analysis

The single invariant

Only the most recent navigation may commit.

Every stale-data bug in a router violates it. Stating it this way collapses four separate bugs — stale loader, back-during-load, redirect race, double submit — into one.

Required invariants

  1. Only the most recent navigation commits.
  2. A superseded navigation's loaders are cancelled and their results discarded.
  3. A redirect during loading prevents the original navigation from committing.
  4. Scroll restoration happens after the content determining page height exists.
  5. Navigation blocking cannot silently swallow a browser back navigation.

The three fixes, and where each stops working

FixStops the work?Correct with a server side effect?
Render-time guardnono — the effect already happened
Sequence numbernono
AbortControllerbest-effortclosest — the server may still have acted

Ship AbortController plus a sequence guard: cancellation is best-effort, so late responses must still be ignored.

The question that separates seniority levels: what if the loader has a server side effect? No client-side fix suffices. You need idempotency keys, or the operation does not belong in a loader. That is an architectural answer, not a code fix.

Platform constraints you cannot engineer around

RealityConsequence
popstate does not report directiontrack indices yourself
pushState does not fire popstatehandle your own navigations explicitly
The history stack is unreadableno "can I go back?" without bookkeeping
Back cannot be cancelledunsaved-changes guards only work for router-controlled navigation

The last is a deliberate platform decision — trapping the back button would be user-hostile — which is why beforeunload is limited to a browser-controlled dialog. The Navigation API exists to give back a principled version of the capability.

The recurring anchoring problem

Restoring scroll before async content resolves scrolls to a position that does not exist and clamps. This is the same problem as fw-10's virtualized list and the browser's own scroll anchoring (bi-08): you cannot restore a position in a document whose size you do not yet know.