[PR #909] [MERGED] Return leaf selected layout segment for named parallel routes #939

Closed
opened 2026-05-06 13:10:57 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/909
Author: @NathanDrake2406
Created: 4/26/2026
Status: Merged
Merged: 4/26/2026
Merged by: @james-elicx

Base: mainHead: nathan/fix-selected-layout-segment-parallel-routes


📝 Commits (1)

  • dd6f56f Return leaf selected layout segment for named slots

📊 Changes

3 files changed (+63 additions, -18 deletions)

View changed files

📝 packages/vinext/src/shims/navigation.ts (+5 -1)
📝 tests/app-router.test.ts (+51 -17)
tests/fixtures/app-basic/app/dashboard/@team/members/profile/page.tsx (+7 -0)

📄 Description

What this changes

useSelectedLayoutSegment(parallelRoutesKey) now matches Next.js for named parallel routes: the default children route still returns the first child segment, while named slots return the active leaf segment from that slot path.

This fixes nested parallel slot routes such as @team/members/profile, where useSelectedLayoutSegments("team") returns ["members", "profile"] and useSelectedLayoutSegment("team") should return "profile".

Why

Vinext previously reduced every segment array with segments[0]. That is only correct for the default children route. Next.js intentionally treats named parallel route keys differently in computeSelectedLayoutSegment():

  • children: first segment
  • non-children parallel route keys: last segment

Source references:

Approach

The shim now returns null for an empty segment list, returns the first segment for undefined or "children", and returns the final segment for named parallel route keys.

The regression test adds a nested @team slot fixture and asserts both behaviours together:

  • useSelectedLayoutSegments("team") exposes the full slot path ["members", "profile"]
  • useSelectedLayoutSegment("team") returns the leaf segment "profile"

Validation

  • vp test run tests/app-router.test.ts -t "useSelectedLayoutSegment"
  • vp check tests/app-router.test.ts packages/vinext/src/shims/navigation.ts tests/fixtures/app-basic/app/dashboard/@team/members/profile/page.tsx

Risks / follow-ups

This is scoped to the client navigation shim reduction rule. It does not change route discovery or segment-map construction, which already preserves the full slot segment path needed for this behaviour.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/909 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 4/26/2026 **Status:** ✅ Merged **Merged:** 4/26/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `nathan/fix-selected-layout-segment-parallel-routes` --- ### 📝 Commits (1) - [`dd6f56f`](https://github.com/cloudflare/vinext/commit/dd6f56f683d8fddab17bde3318d7196df9814740) Return leaf selected layout segment for named slots ### 📊 Changes **3 files changed** (+63 additions, -18 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/shims/navigation.ts` (+5 -1) 📝 `tests/app-router.test.ts` (+51 -17) ➕ `tests/fixtures/app-basic/app/dashboard/@team/members/profile/page.tsx` (+7 -0) </details> ### 📄 Description ## What this changes `useSelectedLayoutSegment(parallelRoutesKey)` now matches Next.js for named parallel routes: the default `children` route still returns the first child segment, while named slots return the active leaf segment from that slot path. This fixes nested parallel slot routes such as `@team/members/profile`, where `useSelectedLayoutSegments("team")` returns `["members", "profile"]` and `useSelectedLayoutSegment("team")` should return `"profile"`. ## Why Vinext previously reduced every segment array with `segments[0]`. That is only correct for the default `children` route. Next.js intentionally treats named parallel route keys differently in `computeSelectedLayoutSegment()`: - `children`: first segment - non-`children` parallel route keys: last segment Source references: - Next.js implementation: https://github.com/vercel/next.js/blob/6d4a405f4ad9a4173f8b06e80e836b8a104f406c/packages/next/src/shared/lib/segment.ts#L32-L49 - Next.js hook delegation: https://github.com/vercel/next.js/blob/6d4a405f4ad9a4173f8b06e80e836b8a104f406c/packages/next/src/client/components/navigation.ts#L310-L338 - Next.js E2E coverage for nested named slots: https://github.com/vercel/next.js/blob/6d4a405f4ad9a4173f8b06e80e836b8a104f406c/test/e2e/app-dir/parallel-routes-use-selected-layout-segment/parallel-routes-use-selected-layout-segment.test.ts#L84-L93 - Hard navigation nested slot expectation: https://github.com/vercel/next.js/blob/6d4a405f4ad9a4173f8b06e80e836b8a104f406c/test/e2e/app-dir/parallel-routes-use-selected-layout-segment/parallel-routes-use-selected-layout-segment.test.ts#L146-L155 ## Approach The shim now returns `null` for an empty segment list, returns the first segment for `undefined` or `"children"`, and returns the final segment for named parallel route keys. The regression test adds a nested `@team` slot fixture and asserts both behaviours together: - `useSelectedLayoutSegments("team")` exposes the full slot path `["members", "profile"]` - `useSelectedLayoutSegment("team")` returns the leaf segment `"profile"` ## Validation - `vp test run tests/app-router.test.ts -t "useSelectedLayoutSegment"` - `vp check tests/app-router.test.ts packages/vinext/src/shims/navigation.ts tests/fixtures/app-basic/app/dashboard/@team/members/profile/page.tsx` ## Risks / follow-ups This is scoped to the client navigation shim reduction rule. It does not change route discovery or segment-map construction, which already preserves the full slot segment path needed for this behaviour. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:10:57 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#939
No description provided.