cloudflare / cloudflare/vinext

App Router: preserve intercepted and parallel-route state across traversal and refresh

Open
#1,369 1 comment 0 reactions 0 assignees View on GitHub
adapter-api-e2e
Dominant language
TypeScript
Stars
8.8k
Forks
406
Avg merge
2d 6h
Merged PRs (30d)
120

Description

> Created from the Next.js Deploy Suite failure inventory: https://github.com/cloudflare/vinext/actions/runs/26163751905
> Related foundation: https://github.com/cloudflare/vinext/issues/1366
> Complements, but does not replace, #1364, which tracks interception route build/resolution failures.

## Problem

Intercepted routes and parallel slots need history-entry restoration to preserve the complete visible route world: source page, modal/intercepted slot, previously active parallel slots, and refresh state. Vinext has planner/lifecycle authority for many slot/interception decisions, but traversal still lacks a per-history-entry visible-state restore primitive.

Without that, back/forward and refresh can reconstruct from the URL/RSC payload and lose the specific slot/source state that was visible for that history entry.

## Failing or adjacent Next.js suites

- `test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts` — 9 failures in the deploy-suite run.
- `test/e2e/app-dir/interception-dynamic-segment/interception-dynamic-segment.test.ts` — 14 failures, currently also covered by #1364 for build/route resolution.
- `test/e2e/app-dir/interception-dynamic-single-segment/interception-dynamic-single-segment.test.ts` — 5 failures.
- `test/e2e/app-dir/interception-routes-multiple-catchall/interception-routes-multiple-catchall.test.ts` — 5 failures.
- `test/e2e/app-dir/interception-dynamic-segment-middleware/interception-dynamic-segment-middleware.test.ts` — 3 failures.
- `test/e2e/app-dir/interception-segments-two-levels-above/interception-segments-two-levels-above.test.ts` — 3 failures.

## Architectural contract

Interception and parallel-route traversal should reuse the same history-entry restoration primitive as normal back/forward. Do not add modal-specific preservation hacks that bypass the planner/lifecycle boundary.

- The history snapshot is input evidence, not authority.
- Planner/lifecycle decisions still own whether source UI, intercepted slots, unmatched/default slots, and mounted parallel slots may remain visible.
- Snapshot restore must carry enough route-state facts to prove the previous visible world, including source/interception context and mounted slot bindings.
- Refresh and traversal must not infer preservation from missing wire entries, URL shape, or cache presence alone.
- Stale or incompatible snapshots must be rejected without partially merging old slot state.

## Recommendation

1. After route-scanner/build failures are separated from #1364, add a focused fixture for: long/source page -> intercepted modal/detail -> back -> source route and slot state are restored.
2. Extend history-entry restoration from #1366 so snapshots include route id, source/interception context, mounted parallel slot bindings, AppElements, layout flags, navigation snapshot, and cache proof compatibility data needed for safe restore.
3. Make traversal restoration lifecycle-approved; stale or incompatible snapshots must not commit.
4. Verify refresh does not drop previously active page/modal slots when Next.js preserves them.
5. Keep planner decisions authoritative: history-entry restore is evidence/input to an approved commit, not a second router hidden behind cache presence.
6. Add hostile sequence coverage: open intercepted route, refresh, back, forward, then navigate to a sibling parallel route without preserving stale modal/source state.

## Acceptance criteria

- Traversal from an intercepted route restores the exact previous source/slot world when the entry is compatible and present.
- Incompatible or missing snapshots fall back without preserving stale intercepted slots.
- Parallel-route refresh and traversal preserve only planner-approved slots.
- The implementation does not introduce route-state writes outside the approved visible commit path.

## Non-goals

- Basic interception segment parsing/build support, tracked separately by #1364.
- Full future Activity hidden-route model beyond Next-compatible history traversal behavior.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.