feat(router): expose opt-in navigation diagnostics#2598
Open
NathanDrake2406 wants to merge 7 commits into
Open
feat(router): expose opt-in navigation diagnostics#2598NathanDrake2406 wants to merge 7 commits into
NathanDrake2406 wants to merge 7 commits into
Conversation
App Router navigation decisions already produce structured traces, but applications cannot observe them at runtime. This makes cache, prefetch, optimistic-shell, fetch, supersession, and commit races dependent on patched bundles. Add a disabled-by-default VINEXT_DEBUG_NAVIGATION flag, a deterministic reporter, thin lifecycle wiring, documentation, and behavior tests. Events include application URLs but never response bodies, cookies, or request headers.
commit: |
Contributor
Performance benchmarksCompared 0 improved · 0 regressed · 6 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
Navigation diagnostics are intentionally an operational debugging stream, but the documentation did not state whether their event shape was stable. Consumers could otherwise mistake field and phase names for a supported public API. Document that the schema is internal and may change between releases.
The diagnostic reporter and commit callbacks were tested separately, so a wiring regression could break cross-boundary navigation correlation without failing the suite. Exercise a real App Router refresh from start through fetch and commit, and derive diagnostic navigation and reuse kinds from the planner-owned unions to prevent type drift.
NathanDrake2406
marked this pull request as draft
July 12, 2026 07:33
Navigation diagnostics flattened planner and commit decisions into parallel fields, losing decision-specific data such as the fresh-fetch reason and obscuring which layer owned each result. Pass reuse facts, reuse decisions, and commit approval decisions through unchanged. Keep the later visible runtime outcome separate because approval does not guarantee that a queued commit becomes visible.
The shared App Router Playwright server enabled navigation diagnostics for every browser test, removing default-disabled coverage and relying on POSIX-only inline environment syntax. Move the lifecycle assertion to a dedicated Playwright project and server, pass the flag through Playwright environment configuration, and run the project independently in CI.
NathanDrake2406
marked this pull request as ready for review
July 12, 2026 09:26
Synchronous App Router history restores commit cached snapshots without entering navigateRsc, so the opt-in diagnostics omit the lifecycle most relevant to mixed-tree traversal reports. Start and settle a correlated traverse lifecycle at the approved snapshot-restore boundary. Cover both the reported dynamic-param sequence and sibling-route Back restoration in the dedicated diagnostics project.
Pages Router request-error tests cleared the one-time register marker, racing the startup assertion in the shared dev server. The navigation diagnostics project could also reuse an optimized app-basic graph compiled without diagnostics during local runs. Preserve the startup marker while clearing request errors, and give the diagnostics project an owned Vite config with forced optimization. The Playwright regressions now exercise both boundaries deterministically.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
VINEXT_DEBUG_NAVIGATION=1build-time flagWhy
Issue #2597 reports a navigation race whose final DOM mixes stale server-layout data with current client params. The reporter needs the existing structured
NavigationTracedecisions at runtime together with the concrete RSC URL, cache key, fetch lifecycle, supersession, history-snapshot restoration, and final commit outcome.Running the PR preview against the reporter's public reproduction now captures the failure: the B RSC request succeeds and reaches an authoritative commit, but that commit preserves the dynamic layout identity carried through the detached optimistic shell. The diagnostics therefore narrow the follow-up fix to the optimistic-to-authoritative preservation boundary rather than history snapshot restoration.
The original diagnostic path entered through
navigateRsc(). Synchronous history-snapshot restores bypass that function, even though they can commit a cached route tree directly. Leaving that boundary unreported made the diagnostics incomplete for the issue's sibling-route Back symptom.This PR adds observability without changing navigation decisions. Refs #2597.
What changed
traversestart followed by acommitted-cachecommitusePathname()restore togetherThe diagnostic schema remains internal and may change between releases.
Validation
vp checkon all seven touched source, fixture, and E2E filesvp test run tests/app-navigation-debug.test.ts tests/app-browser-entry.test.ts(228 tests)vp run vinext#buildapp-router-navigation-debugPlaywright project (3 tests)Risk and compatibility
navigateRsc()lifecycle without a phantom diagnostic event.finallyso failed restore attempts cannot leave stale diagnostic correlation state.Non-goals
References
Refs #2597