Skip to content

fix(router-core): keep match.pathname consistent across nested matches with param parsing#7747

Open
momomuchu wants to merge 1 commit into
TanStack:mainfrom
momomuchu:fix/match-pathname-nested-consistency-7731
Open

fix(router-core): keep match.pathname consistent across nested matches with param parsing#7747
momomuchu wants to merge 1 commit into
TanStack:mainfrom
momomuchu:fix/match-pathname-nested-consistency-7731

Conversation

@momomuchu

@momomuchu momomuchu commented Jul 4, 2026

Copy link
Copy Markdown

match.pathname is inconsistent across nested matches when params.parse/params.stringify are used: a parent route keeps the raw value in its own pathname, but its parsed value leaks into child routes' pathnames.

In matchRoutesInternal (packages/router-core/src/router.ts), each match's pathname is built with interpolatePath from a single shared routeParams object. After building a route's pathname, Object.assign(routeParams, strictParams) wrote that route's params.parse result back into the same shared object, which is then used to interpolate the child routes' pathnames.

This keeps routeParams raw for all interpolatePath calls and accumulates parsed params separately (accumulatedStrictParams), used only for match.params. Parsed-param inheritance semantics are preserved.

Added a match-params.test.ts case asserting pathname consistency across nested matches with parse/stringify. It fails without the fix and passes with it. router-core plus the react/solid/vue router downstream suites pass, tsc clean.

Closes #7731

Summary by CodeRabbit

  • Bug Fixes

    • Improved route parameter handling so nested matches consistently keep parsed values across the match chain.
    • Prevented route params from affecting later pathname values, keeping displayed path segments aligned with the URL.
    • Fixed consistency issues when routes transform dynamic segments between internal and public forms.
  • Tests

    • Added coverage for nested route pathname consistency and parameter parsing behavior.

…s with params.parse

A route's params.parse result was written back into the shared routeParams
object used to interpolate match.pathname for every route in the match
chain, so a parent route's parsed param leaked into the pathname of routes
matched after it.

Keep routeParams raw for pathname interpolation and accumulate parsed
params separately for match.params.
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9b22fcd-85a0-4308-939b-d01b066db4dc

📥 Commits

Reviewing files that changed from the base of the PR and between a3e24c3 and 03cf348.

📒 Files selected for processing (2)
  • packages/router-core/src/router.ts
  • packages/router-core/tests/match-params.test.ts

📝 Walkthrough

Walkthrough

Modifies route matching logic in router-core to track parsed strict params separately from raw params via a new accumulatedStrictParams map, propagating parsed ancestor values down the match chain for consistent match.params. Adds a regression test verifying params/pathname consistency for nested routes using params.parse/stringify.

Changes

Strict Param Propagation Fix

Layer / File(s) Summary
Accumulate and apply strict params across match chain
packages/router-core/src/router.ts
Introduces accumulatedStrictParams to track parsed params separately from raw routeParams, builds each route's strict params from usedParams overlaid with ancestor accumulated values, merges results back into the accumulator, and applies it to match.params in both match creation and the stabilization loop.
Regression test for match consistency
packages/router-core/tests/match-params.test.ts
Adds a match.pathname consistency test suite verifying that parsed params (via params.parse/stringify) are consistently reflected in params across nested matches while pathname remains aligned with raw URL segments.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: package: router-core

Suggested reviewers: nlynzaad, Sheraff

🚥 Pre-merge checks | ✅ 5
✅ 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 is concise and accurately describes the router pathname consistency fix with nested param parsing.
Linked Issues check ✅ Passed The code and new test address #7731 by keeping match.pathname consistent across nested matches while separating parsed params.
Out of Scope Changes check ✅ Passed The changes stay focused on the reported router-core bug and its regression test, with no clear unrelated scope creep.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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.

match.pathname is inconsistent across nested matches with parsed path params

1 participant