Skip to content

fix(app-router): render parallel slots through route groups - #2022

Merged
james-elicx merged 1 commit into
mainfrom
codex/fix-parallel-route-group-depth-20260615-003744
Jun 15, 2026
Merged

fix(app-router): render parallel slots through route groups#2022
james-elicx merged 1 commit into
mainfrom
codex/fix-parallel-route-group-depth-20260615-003744

Conversation

@james-elicx

Copy link
Copy Markdown
Member

Summary

  • preserve a parallel slot's root page when only URL-transparent route groups remain beneath the slot owner
  • add a focused route-graph regression test
  • add a vinext fixture reproducing the upstream Next.js route-group depth behavior

Next.js parity

Ported from:

  • test/e2e/app-dir/parallel-routes-group-depth/parallel-routes-group-depth.test.ts

Before the fix, the slot rendered an empty value instead of Slot Page. The exact pinned Next.js v16.2.6 suite now passes.

Validation

  • exact Next.js deploy-suite test: 1/1 passed
  • route graph/routing tests: 168 passed
  • App Router integration tests: 166 passed
  • scoped vp check
  • vinext build
  • independent review: no actionable findings

@pkg-pr-new

pkg-pr-new Bot commented Jun 14, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@2022
npm i https://pkg.pr.new/vinext@2022

commit: 67949c5

@github-actions

Copy link
Copy Markdown
Contributor
Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
workers-cache preview production
web preview production

@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@ask-bonk ask-bonk Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/bigbonk review — no actionable findings

Reviewed the parallel-slot-through-route-groups fix. The change is correct, minimal, and well-targeted.

What the change does

packages/vinext/src/routing/app-route-graph.ts:1813 replaces the strict isOwnDir (dir === routeDir) check with:

const isActiveUrlLevel = dir === routeDir || segmentsBelow.every(isInvisibleSegment);

This makes a slot use its own page.tsx (active branch) not only at the route's literal directory, but also when the only thing standing between the slot owner and the route's page directory is URL-transparent segments (route groups). That's exactly the upstream Next.js behavior: a slot owner at app/x/ should stay active when the route's page lives at app/x/(children)/page.tsx.

Correctness review

  • Map keying is safe. Slots are keyed by slot.key, which includes the slot dir's relative path (app-route-graph.ts:2083), so slots at different depths never clash; later levels can only override the same slot at the same depth.
  • Empty segmentsBelow adds no new behavior. [].every(...) is true, but segmentsBelow is only empty at the final dirsToCheck entry where segmentIndex === segments.length, and that entry's dir is always routeDir. So the empty case is already covered by the dir === routeDir arm.
  • @/. invisibility is harmless here. segmentsBelow is derived from the route's page directory, which doesn't contain parallel-slot (@) segments, so the route-group ((...)) case is the only one that can flip isActiveUrlLevel, matching the comment's intent.
  • Inherited branch is unaffected for routes with real visible segments below the slot owner (e.g. /dashboard/settings with a @team slot at app/dashboard) — those still fall through to the mirror/default.tsx path.

Verification

  • tests/app-route-graph.test.ts — 56 passed (incl. new route-graph regression)
  • tests/app-router-dev-server.test.ts — 166 passed (incl. new integration test)
  • scoped vp check on the modified file — clean (format, lint, types)

Minor (non-blocking) nits

  • There's an existing helper hasRemainingVisibleSegments(segments, startIndex) (app-route-graph.ts:2683) that is the logical inverse of segmentsBelow.every(isInvisibleSegment). Reusing !hasRemainingVisibleSegments(segments, segmentIndex) would keep the "what counts as visible below this level" logic in one place. Purely a consistency nit — current inline form is correct.

LGTM.

@ask-bonk

ask-bonk Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review posted successfully on PR #2022.

Summary

I reviewed PR #2022 (fix(app-router): render parallel slots through route groups) and found no actionable issues.

The fix at packages/vinext/src/routing/app-route-graph.ts:1813 is correct and minimal. It changes the "is this slot at its active URL level?" test from a strict dir === routeDir to also accept the case where only URL-transparent segments (route groups) sit between the slot owner and the route's page directory:

const isActiveUrlLevel = dir === routeDir || segmentsBelow.every(isInvisibleSegment);

Key correctness checks I verified:

  • No map-key clashes — slots are keyed by path-inclusive slot.key, so different depths can't collide.
  • Empty segmentsBelow adds no new behavior — it only occurs when dir === routeDir already.
  • Inherited (default.tsx) branch unaffected for routes with real visible segments below the slot owner.
  • Scoped vp check clean; tests/app-route-graph.test.ts (56) and tests/app-router-dev-server.test.ts (166) both pass, including the new regression + integration tests.

One non-blocking nit: an existing helper hasRemainingVisibleSegments is the logical inverse of the inlined segmentsBelow.every(isInvisibleSegment) and could be reused for consistency. Current form is correct either way.

LGTM.

github run

@james-elicx
james-elicx marked this pull request as ready for review June 15, 2026 10:31
@james-elicx
james-elicx merged commit 5146b1f into main Jun 15, 2026
55 checks passed
@james-elicx
james-elicx deleted the codex/fix-parallel-route-group-depth-20260615-003744 branch June 15, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant