From 6f9512d3603f343c57599cbf5f437a8fda14b1d5 Mon Sep 17 00:00:00 2001 From: imsherr Date: Wed, 21 Jan 2026 13:53:40 -0500 Subject: [PATCH] fix(router-core): extract params from URL for snapshot when using string navigation When navigating with a string URL (e.g., `navigate({ to: '/items/abc123' })`), the match snapshot was incorrectly using params from the current location (`fromParams`) instead of extracting params from the destination URL. This caused `Route.useParams()` to return undefined for dynamic params in production when the source route didn't have those params in its path. The fix extracts params from the final interpolated pathname using `getMatchedRoutes()` before building the snapshot, ensuring params are always correct regardless of whether explicit `params` were provided. Fixes the case where: - Navigating from `/reviews/123/overview` to `/reviews/123/proposer-budget/abc` - Using `navigate({ to: '/reviews/123/proposer-budget/abc' })` (string URL) - `Route.useParams()` in the destination returned `{ reviewId: '123' }` but `proposerBudgetId` was undefined because it wasn't in the source route's params --- packages/router-core/src/router.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index 6815bcdf322..149cda1f62f 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -1856,10 +1856,13 @@ export class RouterCore< nextState = replaceEqualDeep(currentLocation.state, nextState) // Build match snapshot for fast-path on back/forward navigation - // Use destRoutes and nextParams directly (after stringify) + // Extract params from the interpolated path to ensure correct params + // even when navigating with string URLs (where dest.params is undefined) + const { routeParams: extractedParams } = + this.getMatchedRoutes(nextPathname) const matchSnapshot = buildMatchSnapshotFromRoutes({ routes: destRoutes, - params: nextParams, + params: extractedParams, searchStr, globalNotFoundRouteId: globalNotFoundMatch?.routeId, })