[PR #499] [MERGED] fix: intercept routes (..) climb visible route segments, not filesystem dirs #621

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

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/499
Author: @NathanDrake2406
Created: 3/12/2026
Status: Merged
Merged: 3/12/2026
Merged by: @james-elicx

Base: mainHead: fix/intercept-route-segment-climbing


📝 Commits (1)

  • 1dd9ac9 fix: intercept routes (..) climb visible route segments, not filesystem dirs

📊 Changes

2 files changed (+131 additions, -29 deletions)

View changed files

📝 packages/vinext/src/routing/app-router.ts (+41 -29)
📝 tests/routing.test.ts (+90 -0)

📄 Description

Summary

  • Fixed computeInterceptTarget() to climb by visible route segments instead of filesystem directories. Previously it used path.dirname() which counted route groups like (marketing) as levels, causing (..) and (..)(..) to resolve to the wrong target when route groups sit between visible segments.
  • Consolidated invisible-segment detection into a single isInvisibleSegment() helper, replacing three duplicated inline checks across computeInterceptTarget, convertSegmentsToRouteParts, and hasRemainingVisibleSegments.

Example of the bug

app/a/(group)/b/@modal/(..)(..)target/page.tsx

Visible route path: /a/b. (..)(..) should climb 2 visible segments → root → intercept /target.

Before: path.dirname(path.dirname("app/a/(group)/b")) = "app/a" → produced /a/target (wrong — climbed b then (group), wasting a level on the invisible route group).

After: Walks backward through ["a", "(group)", "b"], counting only visible segments (ba), correctly resolving to /target.

Test plan

  • 3 new test cases covering (..) and (..)(..) with route groups between segments
  • All 90 routing tests pass
  • All 247 app-router tests pass
  • CI: Format, Lint, Typecheck, Vitest, Playwright E2E

🔄 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/499 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 3/12/2026 **Status:** ✅ Merged **Merged:** 3/12/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/intercept-route-segment-climbing` --- ### 📝 Commits (1) - [`1dd9ac9`](https://github.com/cloudflare/vinext/commit/1dd9ac93848239da5a7ca0d44954187df3026da3) fix: intercept routes (..) climb visible route segments, not filesystem dirs ### 📊 Changes **2 files changed** (+131 additions, -29 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/routing/app-router.ts` (+41 -29) 📝 `tests/routing.test.ts` (+90 -0) </details> ### 📄 Description ## Summary - **Fixed `computeInterceptTarget()`** to climb by visible route segments instead of filesystem directories. Previously it used `path.dirname()` which counted route groups like `(marketing)` as levels, causing `(..)` and `(..)(..)` to resolve to the wrong target when route groups sit between visible segments. - **Consolidated invisible-segment detection** into a single `isInvisibleSegment()` helper, replacing three duplicated inline checks across `computeInterceptTarget`, `convertSegmentsToRouteParts`, and `hasRemainingVisibleSegments`. ### Example of the bug ``` app/a/(group)/b/@modal/(..)(..)target/page.tsx ``` Visible route path: `/a/b`. `(..)(..)` should climb 2 visible segments → root → intercept `/target`. **Before:** `path.dirname(path.dirname("app/a/(group)/b"))` = `"app/a"` → produced `/a/target` (wrong — climbed `b` then `(group)`, wasting a level on the invisible route group). **After:** Walks backward through `["a", "(group)", "b"]`, counting only visible segments (`b` → `a`), correctly resolving to `/target`. ## Test plan - [x] 3 new test cases covering `(..)` and `(..)(..)` with route groups between segments - [x] All 90 routing tests pass - [x] All 247 app-router tests pass - [ ] CI: Format, Lint, Typecheck, Vitest, Playwright E2E --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:09:08 +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#621
No description provided.