Skip to content

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Dec 2, 2025

Fixes #6012 (maybe)

Summary by CodeRabbit

  • Bug Fixes

    • Improved route precedence so index routes are selected correctly at the root, preserving proper full path resolution and avoiding incorrect not-found assignments.
    • Better parameter extraction for optional root index routes, ensuring language and other params are captured reliably.
  • Tests

    • Added edge-case tests (including URI-decoding scenarios) to validate the above routing behaviors.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Walkthrough

Adjusts route-tree assignment logic: node.route replacement now prefers index routes over non-index ones and updates node.fullPath from the chosen route; also removes assignment of node.notFound for non-index leaf routes. Adds tests covering optional root-level index param extraction.

Changes

Cohort / File(s) Summary
Route precedence & fullPath handling
packages/router-core/src/new-process-route-tree.ts
Reworked leaf-node route assignment: replace existing route only when none exists or when the incoming route is an index and the existing is not; when replacing, set node.fullPath to route.fullPath ?? route.from. Removed assignment of node.notFound for non-index leaf routes. Added explanatory comments describing precedence.
Edge-case tests
packages/router-core/tests/new-process-route-tree.test.ts
Added tests validating optional root-level index routes correctly match paths like /sv and extract language params, including a URI-decoding variant.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to the conditional that determines route replacement (index vs non-index) and ensure no regressions for nested/pathless layouts.
  • Verify the node.fullPath update logic correctly preserves intended path provenance (fullPath vs from) in all cases.
  • Review the new tests for completeness and edge-case coverage.

Possibly related PRs

Suggested reviewers

  • schiller-manuel
  • nlynzaad

Poem

🐰 A rabbit hopped through the route tree,
Found an index where params should be,
Swapped the leaf with careful grace,
Full paths set in the right place—
Hooray, the params now roam free! 🌿

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main fix: addressing parameter extraction when matching competing optional routes using proper fullPath.
Linked Issues check ✅ Passed The PR fixes issue #6012 by ensuring optional parameters are properly extracted when competing pathless layouts match, through precedence-aware route assignment and correct fullPath usage.
Out of Scope Changes check ✅ Passed All changes are directly focused on fixing the route matching and parameter extraction issue for competing optional routes, with no unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-router-core-competing-optional-routes-use-proper-fullpath

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0cf6b22 and 8c6a211.

📒 Files selected for processing (1)
  • packages/router-core/src/new-process-route-tree.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/router-core/src/new-process-route-tree.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Dec 2, 2025

View your CI Pipeline Execution ↗ for commit 8c6a211

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 8m 10s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 26s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-02 22:56:16 UTC

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/router-core/tests/new-process-route-tree.test.ts (1)

834-864: Good test coverage for issue #6012.

The test correctly validates that when multiple optional routes compete at the root level, the index route takes precedence and uses the proper fullPath for parameter extraction.

Consider adding complementary test cases to ensure robustness:

  • Test when the non-index route should win (e.g., matching /2024/12/02 should extract year/month/day, not language)
  • Test with different ordering of route definitions to verify precedence is consistent
  • Test when both competing routes are index routes or both are non-index routes

These additional cases would help prevent regressions in the precedence logic.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6dc649 and 0cf6b22.

📒 Files selected for processing (2)
  • packages/router-core/src/new-process-route-tree.ts (2 hunks)
  • packages/router-core/tests/new-process-route-tree.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety throughout the codebase

Files:

  • packages/router-core/src/new-process-route-tree.ts
  • packages/router-core/tests/new-process-route-tree.test.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • packages/router-core/src/new-process-route-tree.ts
  • packages/router-core/tests/new-process-route-tree.test.ts
📚 Learning: 2025-11-25T00:18:21.282Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T00:18:21.282Z
Learning: Applies to **/src/routes/**/*.{ts,tsx} : Use file-based routing in src/routes/ directories or code-based routing with route definitions

Applied to files:

  • packages/router-core/src/new-process-route-tree.ts
  • packages/router-core/tests/new-process-route-tree.test.ts
📚 Learning: 2025-11-25T00:18:21.282Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T00:18:21.282Z
Learning: Applies to packages/solid-router/**/*.{ts,tsx} : Solid Router components and primitives should use the tanstack/solid-router package

Applied to files:

  • packages/router-core/src/new-process-route-tree.ts
  • packages/router-core/tests/new-process-route-tree.test.ts
📚 Learning: 2025-10-14T18:59:33.990Z
Learnt from: FatahChan
Repo: TanStack/router PR: 5475
File: e2e/react-start/basic-prerendering/src/routes/redirect/$target/via-beforeLoad.tsx:8-0
Timestamp: 2025-10-14T18:59:33.990Z
Learning: In TanStack Router e2e test files, when a route parameter is validated at the route level (e.g., using zod in validateSearch or param validation), switch statements on that parameter do not require a default case, as the validation ensures only expected values will reach the switch.

Applied to files:

  • packages/router-core/tests/new-process-route-tree.test.ts
📚 Learning: 2025-10-01T18:30:26.591Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.

Applied to files:

  • packages/router-core/tests/new-process-route-tree.test.ts
🧬 Code graph analysis (1)
packages/router-core/tests/new-process-route-tree.test.ts (1)
packages/router-core/src/new-process-route-tree.ts (2)
  • processRouteTree (651-705)
  • findRouteMatch (618-640)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (1)
packages/router-core/src/new-process-route-tree.ts (1)

335-341: Index route precedence fix for issue #6012 is correct and well-implemented.

The conditional logic !node.route || (!node.isIndex && isIndex) correctly prioritizes index routes over non-index routes when assigning routes to leaf nodes. The code comment explicitly documents this precedence rule. The corresponding fullPath update ensures parameter extraction uses the correct route definition.

The test coverage at line 835 validates the key scenario. Index route precedence is tested across multiple test cases (lines 130, 233, 513), confirming the implementation handles the intended behavior correctly.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 2, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6015

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@6015

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6015

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6015

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6015

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6015

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6015

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6015

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6015

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6015

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6015

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6015

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6015

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6015

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6015

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6015

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6015

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6015

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6015

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6015

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@6015

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6015

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6015

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6015

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6015

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6015

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6015

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6015

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6015

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6015

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6015

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6015

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6015

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6015

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6015

commit: 8c6a211

@Sheraff
Copy link
Contributor Author

Sheraff commented Dec 2, 2025

Fix is confirmed

Screenshot 2025-12-02 at 23 46 12

@Sheraff Sheraff merged commit a40f7aa into main Dec 2, 2025
6 checks passed
@Sheraff Sheraff deleted the fix-router-core-competing-optional-routes-use-proper-fullpath branch December 2, 2025 22:57
enBonnet pushed a commit to enBonnet/router that referenced this pull request Dec 6, 2025
…Path for params extraction (TanStack#6015)

* fix(router-core): matching competing optional routes uses proper fullPath for params extraction

* remove debug console.log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing optional param when using pathless layoutes

2 participants