Skip to content

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

Open
momomuchu wants to merge 2 commits 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 2 commits 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 nested route parameter propagation so parsed parameter values are consistently available across all matched routes.
    • Fixed an issue where strict/parsed params could unintentionally influence later pathname interpolation, ensuring match.pathname stays aligned with the original URL segments.
    • Resolved consistency problems for routes that transform dynamic segments using params.parse/params.stringify.
  • Tests

    • Added coverage to verify nested pathname and parameter consistency when dynamic segments are remapped via params.parse/params.stringify.

…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: 4f870694-6e48-4fcb-893a-2474be6c04b7

📥 Commits

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

📒 Files selected for processing (1)
  • .changeset/lazy-poems-repeat.md
✅ Files skipped from review due to trivial changes (1)
  • .changeset/lazy-poems-repeat.md

📝 Walkthrough

Walkthrough

Modifies router-core route matching to propagate parsed ancestor parameters separately from raw route parameters, keeping nested match.params consistent while preserving pathname segments. Adds regression coverage and a patch release entry.

Changes

Strict Param Propagation Fix

Layer / File(s) Summary
Accumulate and apply strict params across match chain
packages/router-core/src/router.ts
Tracks parsed parameters in accumulatedStrictParams, uses ancestor values when building strict params, and applies the accumulated values during match creation and stabilization.
Regression test and release metadata
packages/router-core/tests/match-params.test.ts, .changeset/lazy-poems-repeat.md
Tests nested params.parse/stringify behavior for consistent params and pathname values, and declares a router-core patch release.

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

Suggested labels: package: router-core

Suggested reviewers: nlynzaad, Sheraff

Sequence Diagram(s)

sequenceDiagram
  participant RouteMatcher
  participant StrictParams
  participant NestedMatch

  RouteMatcher->>StrictParams: Accumulate parsed ancestor parameters
  RouteMatcher->>NestedMatch: Set params from accumulated values
  NestedMatch-->>RouteMatcher: Preserve raw pathname segments
Loading
🚥 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 clearly matches the main fix: keeping match.pathname consistent across nested matches with param parsing.
Linked Issues check ✅ Passed The code and regression test directly address #7731 by separating raw pathname interpolation from accumulated parsed params.
Out of Scope Changes check ✅ Passed The changes are scoped to the router fix, its regression test, and the changeset entry; no unrelated work is present.
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