Skip to content

Conversation

nlynzaad
Copy link
Contributor

@nlynzaad nlynzaad commented Sep 11, 2025

This PR resolves #5133 by making the _strictParams more conscious of path defining characters and other wildcards. It also adds e2e tests for react and solid

Summary by CodeRabbit

  • New Features

    • Added “Non-nested path params” pages and links in React and Solid basic-file-based e2e tests at /params-ps/non-nested, plus nested dynamic routes to view single and combined params; UI links and outlets included.
  • Bug Fixes

    • Improved internal path-parameter resolution so strict param extraction uses the full route path for more accurate matching.
  • Tests

    • Added end-to-end tests verifying navigation to /params-ps/non-nested/foo/bar and correct partial vs. full param values.

Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Walkthrough

Adds a non-nested param routes subtree under /params-ps for React and Solid E2E apps, updates generated route trees and tests, and changes RouterCore.matchRoutesInternal to derive strictParams from fullPath interpolation (usedParams).

Changes

Cohort / File(s) Summary
Router core logic
packages/router-core/src/router.ts
matchRoutesInternal now uses interpolatePath(route.fullPath).usedParams as strictParams and inlines interpolatePath for route.id to compute matchId; removed intermediate interpolatePathResult.
React generated route tree
e2e/react-router/basic-file-based/src/routeTree.gen.ts
Adds /params-ps/non-nested subtree, imports new route modules, creates WithChildren wrappers, updates public type maps and @tanstack/react-router augmentation.
React non-nested routes
e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx, .../non-nested/route.tsx, .../non-nested/$foo_/route.tsx, .../non-nested/$foo_/$bar.tsx
Adds index link to non-nested demo; creates non-nested route, parent $foo_ outlet, and leaf route that reads params via useParams({ from: '/params-ps/non-nested/$foo_' }) and Route.useParams().
React tests
e2e/react-router/basic-file-based/tests/params.spec.ts
Adds E2E verifying navigation to /params-ps/non-nested/foo/bar and asserting both partial and full params resolved.
Solid generated route tree
e2e/solid-router/basic-file-based/src/routeTree.gen.ts
Mirrors React: adds /params-ps and /params-ps/non-nested subtree, imports, WithChildren wrappers, type maps, and @tanstack/solid-router augmentation.
Solid non-nested routes
e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx, .../non-nested/route.tsx, .../non-nested/$foo_/route.tsx, .../non-nested/$foo_/$bar.tsx
Adds index with links; non-nested route, $foo_ parent outlet, and leaf route rendering params via useParams({ from: '/params-ps/non-nested/$foo_' }) and Route.useParams().
Solid tests
e2e/solid-router/basic-file-based/tests/params.spec.ts
Adds E2E verifying non-nested params resolution identical to React suite.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant R as RouterCore.matchRoutesInternal
  participant P as interpolatePath
  participant RT as RouteTree

  U->>R: Navigate to /params-ps/non-nested/foo/bar
  R->>P: interpolate(route.fullPath, incomingParams)
  P-->>R: { interpolatedPath, usedParams }
  Note right of R: strictParams := usedParams
  R->>P: interpolate(route.id, leaveWildcards=true)
  P-->>R: { interpolatedPath: matchId }
  R->>RT: build match (pathname from fullPath, id from matchId)
  U->>R: useParams({ from: '/params-ps/non-nested/$foo_' })
  R-->>U: { foo: 'foo' }
  U->>R: Route.useParams() at leaf /$foo_/$bar
  R-->>U: { foo: 'foo', bar: 'bar' }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Suggested labels

package: react-router, package: solid-router

Suggested reviewers

  • schiller-manuel
  • Sheraff
  • SeanCassiere

Poem

I hopped through paths where underscores hide,
Sniffed out $foo and $bar with pride.
From fullPath crumbs, strictParams grew,
Now useParams finds what is true.
Hops, links, tests — carrots all in view! 🥕


📜 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 66ec1bf and 8a5da44.

📒 Files selected for processing (4)
  • e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx
  • e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx
  • e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (3)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)
  • Route (3-5)
⏰ 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). (1)
  • GitHub Check: Test
🔇 Additional comments (2)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (2)

1-1: Import looks correct for Solid Router.


3-3: Component-less parent param route verified — no change required

Generated route tree contains '/params-ps/non-nested/$foo_' (and child '/params-ps/non-nested/$foo_/$bar') and e2e/solid-router/basic-file-based params.spec.ts navigates to '/params-ps/non-nested' and asserts '/params-ps/non-nested/foo/bar'.

Optional: add a one-line comment above createFileRoute stating it's intentionally component-less.

Pre-merge checks (4 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change — a router-core fix targeting _strictParams and handling of path-defining characters — and aligns with the modified router-core code and added tests in this PR.
Linked Issues Check ✅ Passed The changes address issue #5133 by updating RouterCore.matchRoutesInternal to derive strictParams from the interpolated fullPath and by adding React and Solid e2e tests that exercise underscore-suffixed params (e.g., $foo), which matches the reported regression and the expected behavior described in the linked issue.
Out of Scope Changes Check ✅ Passed All reported modifications appear directly related to implementing and validating the fix: the router-core logic change implements the behavioral fix and the added route files, generated route-tree updates, and e2e tests for React and Solid are test scaffolding to validate that behavior; no unrelated or unexpected changes are evident in the provided summaries.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch #5133

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

Copy link

nx-cloud bot commented Sep 11, 2025

View your CI Pipeline Execution ↗ for commit 8a5da44

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

☁️ Nx Cloud last updated this comment at 2025-09-11 21:22:01 UTC

Copy link

pkg-pr-new bot commented Sep 11, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-plugin

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-plugin

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-server-functions-client

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

@tanstack/start-server-functions-fetcher

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

@tanstack/start-server-functions-server

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/zod-adapter

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

commit: 8a5da44

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: 0

🧹 Nitpick comments (6)
packages/router-core/src/router.ts (1)

1186-1191: Optional: pass parseCache to interpolatePath(route.fullPath) for consistency and perf.
Keeps parsing cached like the matchId call.

Apply:

-      const { interpolatedPath, usedParams } = interpolatePath({
+      const { interpolatedPath, usedParams } = interpolatePath({
         path: route.fullPath,
         params: routeParams,
         decodeCharMap: this.pathParamsDecodeCharMap,
+        parseCache: this.parsePathnameCache,
       })
e2e/solid-router/basic-file-based/tests/params.spec.ts (2)

139-140: Stabilize waitForURL matching: use a glob pattern

The literal string may not match the full absolute URL. Prefer a glob to avoid flakiness.

-    await page.waitForURL('/params-ps/non-nested')
+    await page.waitForURL('**/params-ps/non-nested')

152-160: Prefer textContent() and inline parse to reduce layout dependency

innerText triggers layout and can be slower/flaky. textContent is faster and sufficient here.

-    const fooParamsValue = page.getByTestId('foo-params-value')
-    const fooParamsText = await fooParamsValue.innerText()
-    const fooParamsObj = JSON.parse(fooParamsText)
-    expect(fooParamsObj).toEqual({ foo: 'foo' })
+    const fooParamsText = await page.getByTestId('foo-params-value').textContent()
+    expect(JSON.parse(fooParamsText ?? '{}')).toEqual({ foo: 'foo' })
-
-    const paramsValue = page.getByTestId('foo-bar-params-value')
-    const paramsText = await paramsValue.innerText()
-    const paramsObj = JSON.parse(paramsText)
-    expect(paramsObj).toEqual({ foo: 'foo', bar: 'bar' })
+    const paramsText = await page.getByTestId('foo-bar-params-value').textContent()
+    expect(JSON.parse(paramsText ?? '{}')).toEqual({ foo: 'foo', bar: 'bar' })
e2e/react-router/basic-file-based/tests/params.spec.ts (1)

64-65: Stabilize waitForURL matching: use a glob pattern

Use a glob to match the absolute URL and avoid hangs/flakes.

-    await page.waitForURL('/params-ps/non-nested')
+    await page.waitForURL('**/params-ps/non-nested')
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)

10-24: Move Outlet outside of

    for valid markup

      should contain only
    • children. Place after the list (or wrap in
    • ).
      -      <ul className="grid mb-2">
      -        <li>
      -          <Link
      -            from={Route.fullPath}
      -            data-testid="l-to-non-nested-foo-bar"
      -            to="./$foo/$bar"
      -            params={{ foo: 'foo', bar: 'bar' }}
      -          >
      -            /params-ps/non-nested/$foo/$bar
      -          </Link>
      -        </li>
      -        <Outlet />
      -      </ul>
      +      <ul className="grid mb-2">
      +        <li>
      +          <Link
      +            from={Route.fullPath}
      +            data-testid="l-to-non-nested-foo-bar"
      +            to="./$foo/$bar"
      +            params={{ foo: 'foo', bar: 'bar' }}
      +          >
      +            /params-ps/non-nested/$foo/$bar
      +          </Link>
      +        </li>
      +      </ul>
      +      <Outlet />
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)

10-24: Move Outlet outside of

    for valid markup

    Ensure list semantics; mirror the React fix.

    -      <ul class="grid mb-2">
    -        <li>
    -          <Link
    -            from={Route.fullPath}
    -            data-testid="l-to-non-nested-foo-bar"
    -            to="./$foo/$bar"
    -            params={{ foo: 'foo', bar: 'bar' }}
    -          >
    -            /params-ps/non-nested/$foo/$bar
    -          </Link>
    -        </li>
    -        <Outlet />
    -      </ul>
    +      <ul class="grid mb-2">
    +        <li>
    +          <Link
    +            from={Route.fullPath}
    +            data-testid="l-to-non-nested-foo-bar"
    +            to="./$foo/$bar"
    +            params={{ foo: 'foo', bar: 'bar' }}
    +          >
    +            /params-ps/non-nested/$foo/$bar
    +          </Link>
    +        </li>
    +      </ul>
    +      <Outlet />
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a600223 and 3cf7a9e.

📒 Files selected for processing (13)
  • e2e/react-router/basic-file-based/src/routeTree.gen.ts (29 hunks)
  • e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx (2 hunks)
  • e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/tests/params.spec.ts (1 hunks)
  • e2e/solid-router/basic-file-based/src/routeTree.gen.ts (30 hunks)
  • e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/tests/params.spec.ts (1 hunks)
  • packages/router-core/src/router.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (8)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (3)
e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx (3)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (3)
e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (3)
e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (3)
e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (3)
e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)
  • Route (3-5)
packages/router-core/src/router.ts (1)
packages/router-core/src/path.ts (1)
  • interpolatePath (371-485)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (3)
e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx (1)
  • Route (3-5)
⏰ 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 (23)
e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx (2)

1-1: LGTM: consolidated import is clean and consistent.


71-79: LGTM: new “Non-nested path params” nav entry wired correctly.
Link target and data-testid match the new routes/tests.

packages/router-core/src/router.ts (2)

1198-1205: LGTM: inline matchId interpolation keeps ID stability and avoids extra temp vars.
Includes decodeCharMap and parseCache; behavior preserved with loaderDepsHash.


1213-1214: Approve: strictParams now derived from fullPath usedParams — fixes underscore-suffixed params.

E2E routes/links present; no interpolation-based strictParams usage found; no direct useParams({ from: '/params-ps/non-nested/$foo_' }) references.

Matches: e2e/react-router/basic-file-based/tests/params.spec.ts; e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/route.tsx; e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx

e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (2)

3-5: LGTM: parent param route registered correctly.
Path matches the directory and pairs with the $bar child.


7-9: LGTM: Outlet-only wrapper is appropriate for a parent route.

e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/route.tsx (1)

3-9: LGTM: route shell and path are correct

Non-nested parent with Outlet is wired correctly to “/params-ps/non-nested/$foo_”.

e2e/react-router/basic-file-based/tests/params.spec.ts (1)

77-85: Prefer textContent() and inline parse to reduce layout dependency

Switch to textContent and inline JSON.parse for brevity and stability.

File: e2e/react-router/basic-file-based/tests/params.spec.ts (lines 77-85)

-    const fooParamsValue = page.getByTestId('foo-params-value')
-    const fooParamsText = await fooParamsValue.innerText()
-    const fooParamsObj = JSON.parse(fooParamsText)
-    expect(fooParamsObj).toEqual({ foo: 'foo' })
+    const fooParamsText = await page.getByTestId('foo-params-value').textContent()
+    expect(JSON.parse(fooParamsText ?? '{}')).toEqual({ foo: 'foo' })
-
-    const paramsValue = page.getByTestId('foo-bar-params-value')
-    const paramsText = await paramsValue.innerText()
-    const paramsObj = JSON.parse(paramsText)
-    expect(paramsObj).toEqual({ foo: 'foo', bar: 'bar' })
+    const paramsText = await page.getByTestId('foo-bar-params-value').textContent()
+    expect(JSON.parse(paramsText ?? '{}')).toEqual({ foo: 'foo', bar: 'bar' })

Quick scan for literal waitForURL globs returned no matches — verify there are no other instances.

e2e/solid-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)

7-19: LGTM: params accessors used correctly for Solid

useParams accessor and Route.useParams signals are rendered as JSON as expected.

e2e/react-router/basic-file-based/src/routes/params-ps/non-nested/$foo_/$bar.tsx (1)

7-19: LGTM: React params usage aligns with API

React version correctly renders plain objects from useParams/Route.useParams.

e2e/solid-router/basic-file-based/src/routes/params-ps/index.tsx (1)

7-33: LGTM: index wiring and test IDs match e2e

Links and headings align with tests; Solid’s class usage is correct.

e2e/react-router/basic-file-based/src/routeTree.gen.ts (6)

41-41: LGTM: imports for the new non-nested params subtree are correct.

Paths resolve to expected route modules under params-ps/non-nested.

Also applies to: 65-65, 73-73


225-229: LGTM: route wiring preserves $foo_ semantics.

  • Parent/child relationships are correct.
  • id retains $foo_ while path/fullPath use $foo as expected.

Also applies to: 354-359, 399-403


451-451: Type maps updated consistently (fullPath vs id).

  • fullPath/To entries use $foo; Ids use $foo_. No collisions evident.

Please run the new E2E to confirm useParams({ from: '/params-ps/non-nested/$foo_' }) returns foo as expected across navigations.

Also applies to: 467-467, 492-492, 514-514, 529-529, 554-554, 580-580, 599-599, 624-624, 650-650, 666-666, 691-691, 713-713, 728-728, 753-753, 778-778, 797-797, 822-822


1071-1077: LGTM: module augmentation entries match id/path/fullPath expectations.

preLoaderRoute and parentRoute pairings look correct.

Also applies to: 1239-1245, 1295-1301


1397-1424: LGTM: WithChildren wrappers for the non-nested subtree.

Children collections correctly expose $bar under $foo_.


848-848: LGTM: root children exposure.

ParamsPsNonNestedRouteRoute is surfaced in both the type and runtime maps.

Also applies to: 1563-1564

e2e/solid-router/basic-file-based/src/routeTree.gen.ts (6)

28-28: LGTM: new imports for params-ps index and non-nested subtree.

Solid parity with React is clear.

Also applies to: 39-39, 56-56, 64-64


147-151: LGTM: added routes and hierarchy for /params-ps and non-nested foo/bar.

id/path alignment mirrors the underscore semantics.

Also applies to: 204-208, 294-299, 339-343


390-400: Type surfaces expanded correctly.

  • Full paths include $foo variants; Ids include $foo_ variants only where appropriate.

Please run the Solid E2E for the new routes to validate useParams from ‘from’ strings containing $foo_.

Also applies to: 405-406, 423-424, 444-445, 452-453, 458-459, 476-477, 501-502, 513-514, 519-520, 537-538, 562-563, 571-572, 578-579, 595-596, 616-617, 625-626, 631-632, 648-649, 672-673, 685-686, 691-692, 709-710


857-863: LGTM: module augmentation entries for Solid.

id/path/fullPath/preLoaderRoute/parentRoute all line up.

Also applies to: 934-940, 1053-1059, 1109-1115


1211-1238: LGTM: WithChildren wrappers for non-nested subtree.

Child exposure matches expected structure.


733-734: LGTM: RootRouteChildren now exposes both index and non-nested groups.

React/Solid parity maintained.

Also applies to: 739-740

@nlynzaad nlynzaad merged commit 2b6789b into main Sep 11, 2025
6 checks passed
@nlynzaad nlynzaad deleted the #5133 branch September 11, 2025 21:27
nlynzaad added a commit that referenced this pull request Sep 11, 2025
nlynzaad added a commit that referenced this pull request Sep 11, 2025
…5136)

merges PR #5135 into alpha

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
LadyBluenotes pushed a commit to LadyBluenotes/router that referenced this pull request Sep 19, 2025
…k#5135)

This PR resolves TanStack#5133 by making the _strictParams more conscious of
path defining characters and other wildcards. It also adds e2e tests for
react and solid

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added “Non-nested path params” pages and links in React and Solid
basic-file-based e2e tests at /params-ps/non-nested, plus nested dynamic
routes to view single and combined params; UI links and outlets
included.

- **Bug Fixes**
- Improved internal path-parameter resolution so strict param extraction
uses the full route path for more accurate matching.

- **Tests**
- Added end-to-end tests verifying navigation to
/params-ps/non-nested/foo/bar and correct partial vs. full param values.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

Route segments postfixed with _ aren't being included in params with useParams

1 participant