Skip to content

Conversation

nlynzaad
Copy link
Contributor

@nlynzaad nlynzaad commented Sep 22, 2025

as part of #5169 we made changes to strip underscores from the paths to ensure it is dealt with correctly during parsing.

inadvertently this stripped it from not only the route segments but also the base segments. This PR resolves that issue by making baseParsePathName aware which type of segments it is parsing.

a new optional boolean paramater, basePathValues, is introduced in baseParsePathName and parsePathname to allow this distinction between routeSegments and/or basesegments to be passed on to baseParsePathName.

2 new functions are introduced parseBasePathSegments and parseRoutePathSegments, which is just wrapper functions around parsePathname, but ensures clearer understanding of what set of parsing instructions is applied and basePathValues is set correctly based on the requirement.

updated the unit tests to take into account the need not to strip the base values and also enhanced the e2e tests as well to ensure more through testing with different usages.

Summary by CodeRabbit

  • New Features
    • Added non-nested route demos (named, prefix, suffix, path) with index/foo/bar pages and updated navigation in React and Solid examples.
  • Bug Fixes
    • Improved path parsing/matching to handle non-nested segments, prefixes/suffixes and trailing underscores; refined route sorting/resolution.
  • Tests
    • Added comprehensive E2E coverage for non-nested paths; removed obsolete baz-based tests.
    • Expanded unit tests for path interpolation and matching (underscore, prefix/suffix cases).

Copy link
Contributor

coderabbitai bot commented Sep 22, 2025

Walkthrough

Adds four new non-nested route families (named, path, prefix, suffix) across React and Solid e2e apps and removes legacy baz routes. Regenerates route trees and types. Introduces parseBasePathSegments/parseRoutePathSegments and adjusts internal parsing/matching callers; updates tests to cover underscore/non-nested behavior.

Changes

Cohort / File(s) Summary
Router-core parsing
packages/router-core/src/path.ts, packages/router-core/src/process-route-tree.ts
Added parseBasePathSegments and parseRoutePathSegments, added basePathValues flag to parsing functions, updated signatures, and switched internal callers (resolvePath, interpolatePath, matchByPath, sortRoutes) to the new helpers.
Router-core tests
packages/router-core/tests/path.test.ts, packages/router-core/tests/match-by-path.test.ts
Expanded tests for interpolation/matching to include trailing-underscore, prefix/suffix, and named/wildcard param scenarios; updated expectations to reflect non-nested parsing behavior.
React e2e route tree gen
e2e/react-router/basic-file-based/src/routeTree.gen.ts
Regenerated to add /non-nested/{named,path,prefix,suffix} families, new child routes, and updated public maps/types; removed baz-based entries.
React e2e routes added
e2e/react-router/basic-file-based/src/routes/non-nested/...
Added route files for named/*, path/*, prefix/*, suffix/* (route/.route.tsx, index, foo, .bar variants), and updated non-nested/route.tsx links.
React e2e routes removed
e2e/react-router/basic-file-based/src/routes/non-nested/baz.tsx, .../baz.$bazid.tsx, .../baz_.$bazid.edit.tsx
Deleted legacy baz routes and edit variant.
React e2e tests
e2e/react-router/basic-file-based/tests/app.spec.ts, e2e/react-router/basic-file-based/tests/non-nested-paths.spec.ts
Removed old baz nesting test; added parameterized non-nested-paths tests covering named/prefix/suffix/path flows and param propagation.
Solid e2e route tree gen
e2e/solid-router/basic-file-based/src/routeTree.gen.ts
Regenerated to include the same /non-nested families and updated public route/type surfaces; removed baz-based entries.
Solid e2e routes added
e2e/solid-router/basic-file-based/src/routes/non-nested/...
Added named/*, path/*, prefix/*, suffix/* routes mirroring React set; updated non-nested/route.tsx links.
Solid e2e routes removed
e2e/solid-router/basic-file-based/src/routes/non-nested/baz.tsx, .../baz.$bazid.tsx, .../baz_.$bazid.edit.tsx
Deleted legacy baz routes and edit variant.
Solid e2e tests
e2e/solid-router/basic-file-based/tests/app.spec.ts, e2e/solid-router/basic-file-based/tests/non-nested-paths.spec.ts
Removed old baz nesting test; added non-nested-paths Playwright tests exercising param and visibility assertions across cases.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as Link / Navigation
  participant Router as Router
  participant ParseBase as parseBasePathSegments
  participant ParseRoute as parseRoutePathSegments
  participant Matcher as matchByPath

  UI->>Router: navigate(from, to, params)
  Router->>ParseBase: parseBasePathSegments(from)
  Router->>ParseRoute: parseRoutePathSegments(to)
  Router->>Matcher: matchByPath(fromSegments, toSegments)
  Matcher-->>Router: match result (params, route)
  Router-->>UI: render matched route (components / Outlet)
  note right of ParseBase: handles basePathValues (trailing underscores/non-nested)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

Possibly related PRs

Suggested reviewers

  • Sheraff
  • schiller-manuel

Poem

A rabbit hops through routes anew,
From baz to named, prefix, suffix, too—
Parsers nibble underscores just right,
Links find paths by day and night.
Tests hop in place, all green and true. 🐇✨

Pre-merge checks and finishing touches

❌ 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 (2 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 summarizes the primary change: limiting underscore stripping to route segments in router-core rather than base segments, which aligns with the PR objectives (adding basePathValues, parseBasePathSegments/parseRoutePathSegments, and related test updates) and the changes to packages/router-core/src/path.ts described in the diff. The phrasing is concise, specific, and clearly reflects the main intent of the changeset.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch non-nested-paths

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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

Copy link

nx-cloud bot commented Sep 22, 2025

View your CI Pipeline Execution ↗ for commit 5aa2f1d

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

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

Copy link

pkg-pr-new bot commented Sep 22, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-plugin

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-plugin

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-server-functions-client

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

@tanstack/start-server-functions-fetcher

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

@tanstack/start-server-functions-server

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/zod-adapter

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

commit: 5aa2f1d

@nlynzaad nlynzaad changed the title fix(router-core): Non nested paths only strip underscore on route segments fix(router-core): Non nested paths - only strip underscore on route segments Sep 22, 2025
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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx (1)

1-21: Replace lingering "nested" headings with "non-nested"
Update the visible headings to "Hello non-nested suffix index" and "Hello non-nested suffix foo page" in:

  • e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx:12
  • e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx:13
  • e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx:12
  • e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx:13
packages/router-core/src/path.ts (3)

589-596: Pre-check for basepath ignores caseSensitive=false.

This can incorrectly return undefined when basepath differs only by case. Make the check case-aware or remove it and rely on removeBasepath.

-  if (basepath !== '/' && !from.startsWith(basepath)) {
+  if (
+    basepath !== '/' &&
+    (caseSensitive
+      ? !from.startsWith(basepath)
+      : !from.toLowerCase().startsWith(basepath.toLowerCase()))
+  ) {
     return undefined
   }

463-468: Wrong key used when leaveParams=true (named params).

encodeParam expects the param key (e.g., 'id'), but segment.value includes the '$' prefix. This yields undefined interpolation.

-        if (leaveParams) {
-          const value = encodeParam(segment.value)
+        if (leaveParams) {
+          const value = encodeParam(key)
           return `${segmentPrefix}${segment.value}${value ?? ''}${segmentSuffix}`
         }

491-499: Same bug for optional params with leaveParams=true.

Use the decoded key.

-        if (leaveParams) {
-          const value = encodeParam(segment.value)
+        if (leaveParams) {
+          const value = encodeParam(key)
           return `${segmentPrefix}${segment.value}${value ?? ''}${segmentSuffix}`
         }
🧹 Nitpick comments (32)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)

11-16: Verify test-id naming vs. path semantics (baz vs. baz_).

Data-testids omit the underscore (baz instead of baz_). If test selectors or docs rely on reflecting the exact path semantics, consider aligning the id or confirm tests intentionally normalize it.

e2e/react-router/basic-file-based/src/routes/non-nested/suffix/route.tsx (1)

14-14: Wrap links in a nav for basic a11y semantics.
Use a

with an aria-label around the link block.

-      <div>
+      <nav aria-label="Non-nested suffix links">
@@
-      </div>
+      </nav>

Also applies to: 54-54

e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx (1)

11-13: Fix copy: “nested” vs “non‑nested”.
Heading says “nested” but this route family is “non‑nested”.

-        Hello nested suffix index
+        Hello non-nested suffix index
e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx (1)

12-16: Fix copy: “nested” vs “non‑nested”.
Align with the rest of the non‑nested suffix routes.

-        Hello nested suffix foo page
+        Hello non-nested suffix foo page
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)

13-13: Use a nav landmark for the links block.
Improves semantics; no behavior change.

-      <div>
+      <nav aria-label="Non-nested path links">
@@
-      </div>
+      </nav>

Also applies to: 29-29

e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)

13-13: Mirror the React a11y nav wrapper here too.

-      <div>
+      <nav aria-label="Non-nested path links">
@@
-      </div>
+      </nav>

Also applies to: 29-29

e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)

11-12: Inconsistent heading text.

The heading shows "Hello nested path baz index" but this is a non-nested route. The text should be consistent with the route type.

Apply this diff to fix the heading text:

-        Hello nested path baz index
+        Hello non-nested path baz index
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)

12-13: Inconsistent heading text.

Similar to the index route, the heading shows "Hello nested path baz foo page" but this is a non-nested route.

Apply this diff to fix the heading text:

-        Hello nested path baz foo page
+        Hello non-nested path baz foo page
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)

10-12: Use a semantic heading element for the layout title

Prefer an h* tag over a div for better semantics and a11y.

Apply:

-      <div data-testid="non-nested-path-baz-route-heading">
-        Hello non-nested path baz route layout
-      </div>
+      <h3 data-testid="non-nested-path-baz-route-heading">
+        Hello non-nested path baz route layout
+      </h3>
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)

12-14: Microcopy: “nested” → “non-nested”

The page text conflicts with the route family name and other files.

Apply:

-      <div data-testid="non-nested-named-baz-foo-heading">
-        Hello nested named baz foo page
-      </div>
+      <div data-testid="non-nested-named-baz-foo-heading">
+        Hello non-nested named baz foo page
+      </div>
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)

16-17: Consistency: make relative “to” paths explicit with ./ (optional)

Not required functionally, but matches the React examples and improves readability.

Apply:

-          to="prefix{$baz}"
+          to="./prefix{$baz}"
-          to="prefix{$baz}/foo"
+          to="./prefix{$baz}/foo"
-          to="prefix{$baz}/foo"
+          to="./prefix{$baz}/foo"
-          to="prefix{$baz}/bar"
+          to="./prefix{$baz}/bar"
-          to="prefix{$baz}/bar"
+          to="./prefix{$baz}/bar"

Also applies to: 24-25, 32-33, 40-41, 48-49

e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)

11-13: Microcopy: “nested” → “non-nested”

Align heading text with the non-nested route family.

Apply:

-      <div data-testid="non-nested-prefix-baz-index-heading">
-        Hello nested prefix index
-      </div>
+      <div data-testid="non-nested-prefix-baz-index-heading">
+        Hello non-nested prefix index
+      </div>
e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)

14-53: Reduce duplication in Link blocks (optional)

You can map over a small config array to avoid repeating nearly identical Link elements.

Example:

const links = [
  { to: "./$baz", testId: "to-named-index" },
  { to: "./$baz/foo", testId: "to-named-foo" },
  { to: "./$baz/foo", testId: "to-named-foo-2", params: { baz: "baz_" } },
  { to: "./$baz/bar", testId: "to-named-bar" },
  { to: "./$baz/bar", testId: "to-named-bar-2", params: { baz: "baz_" } },
]
e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx (1)

11-13: Microcopy: “nested” → “non-nested”

Match the rest of the non-nested suite.

Apply:

-      <div data-testid="non-nested-suffix-baz-index-heading">
-        Hello nested suffix index
-      </div>
+      <div data-testid="non-nested-suffix-baz-index-heading">
+        Hello non-nested suffix index
+      </div>
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)

11-13: Adjust copy to avoid confusion with "non-nested" context

Use “non-nested” in the heading to match the route group’s intent.

-        Hello nested prefix index
+        Hello non-nested prefix index
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)

12-14: Nit: align heading with "non-nested" terminology

Small copy tweak for consistency across the suite.

-        Hello nested path baz foo page
+        Hello non-nested path baz foo page
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)

11-13: Nit: align heading with "non-nested" terminology

Keep naming consistent with folder/route purpose.

-        Hello nested named baz index
+        Hello non-nested named baz index
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)

12-14: Nit: align heading with "non-nested" terminology

Minor copy update.

-        Hello nested prefix foo page
+        Hello non-nested prefix foo page
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)

11-13: Nit: align heading with "non-nested" terminology

Minor copy consistency.

-        Hello nested path baz index
+        Hello non-nested path baz index
e2e/react-router/basic-file-based/tests/non-nested-paths.spec.ts (4)

107-107: Remove noisy console log

This adds noise to CI logs without aiding assertions.

-          console.log(await indexLink.getAttribute('href'))

108-110: Make href assertions tolerant to optional trailing slash

Prevents flakiness if link generation normalizes slashes.

-          await expect(indexLink).toHaveAttribute('href', indexPath)
-          await expect(fooLink).toHaveAttribute('href', fooPath)
-          await expect(foo2Link).toHaveAttribute('href', foo2Path)
+          await expect(indexLink).toHaveAttribute('href', new RegExp(`^${indexPath}/?$`))
+          await expect(fooLink).toHaveAttribute('href', new RegExp(`^${fooPath}/?$`))
+          await expect(foo2Link).toHaveAttribute('href', new RegExp(`^${foo2Path}/?$`))

113-114: Wait for URL using regex to handle optional trailing slash

Reduces brittleness across environments or future router changes.

-          await page.waitForURL(indexPath)
+          await page.waitForURL(new RegExp(`^${indexPath}/?$`))

-          await page.waitForURL(fooPath)
+          await page.waitForURL(new RegExp(`^${fooPath}/?$`))

-          await page.waitForURL(foo2Path)
+          await page.waitForURL(new RegExp(`^${foo2Path}/?$`))

-          await page.waitForURL(barPath)
+          await page.waitForURL(new RegExp(`^${barPath}/?$`))

-          await page.waitForURL(bar2Path)
+          await page.waitForURL(new RegExp(`^${bar2Path}/?$`))

Also applies to: 121-122, 129-130, 174-175, 182-183


176-176: Prefer absence checks over visibility for non-nested assertion

Use count=0 to assert the element isn’t rendered at all (stronger than not visible).

-          await expect(pathRouteHeading).not.toBeVisible()
+          await expect(pathRouteHeading).toHaveCount(0)

Also applies to: 184-184

e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)

11-13: Heading copy looks inconsistent with route shape.

This route tests a prefix param, not a wildcard. Consider tightening the copy to avoid confusion in e2e assertions and future readers.

Apply this diff:

-        Hello non-nested wildcard bar
+        Hello non-nested prefix bar
e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx (1)

12-14: Minor copy nit: “nested” vs “non-nested”.

This lives under non-nested tests; align the heading.

-        Hello nested suffix foo page
+        Hello non-nested suffix foo page
packages/router-core/tests/path.test.ts (2)

1167-1383: Consider adding a regression test for parse cache base-vs-route semantics.

Current cache keying in src/path.ts ignores the basePathValues flag (see separate comment). A focused test will catch regressions.

+import { parseBasePathSegments, parseRoutePathSegments } from '../src/path'
+
+describe('parsePathname cache behavior', () => {
+  it('distinguishes base vs route parsing for the same pathname', () => {
+    // Shared cache simulates production usage
+    const cache = new Map() as unknown as import('../src/path').ParsePathnameCache
+    const routeParsed = parseRoutePathSegments('/a_', cache)
+    expect(routeParsed.at(-1)?.value).toBe('a')   // underscore trimmed for route
+    const baseParsed = parseBasePathSegments('/a_', cache)
+    expect(baseParsed.at(-1)?.value).toBe('a_')  // must NOT be trimmed for base
+  })
+})

586-866: Add a basepath case-insensitive match test.

matchByPath has a pre-check that currently ignores caseSensitive=false. Add a test to prevent regressions after the fix in src/path.ts.

+describe('matchPathname basepath case-insensitive', () => {
+  it('matches when basepath differs only by case', () => {
+    expect(matchPathname('/App', '/app/abc', { to: '/abc', caseSensitive: false })).toStrictEqual({})
+  })
+})
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)

11-13: Minor copy nit: “nested” vs “non-nested”.

Align heading with the non-nested route family.

-        Hello nested named baz index
+        Hello non-nested named baz index
e2e/solid-router/basic-file-based/tests/non-nested-paths.spec.ts (1)

107-107: Remove leftover debug logging.

Console noise slows CI and obscures failures.

-          console.log(await indexLink.getAttribute('href'))
packages/router-core/src/path.ts (3)

365-371: Trailing-slash branch mutates the wrong slice (likely a no-op/bug).

substring(1) removes a leading char, not the trailing slash. Since pathname isn’t used after this, drop the mutation for clarity.

-  if (pathname.slice(-1) === '/') {
-    pathname = pathname.substring(1)
+  if (pathname.slice(-1) === '/') {
     segments.push({
       type: SEGMENT_TYPE_PATHNAME,
       value: '/',
     })
   }

283-286: Comment accuracy/wording.

“strip tailing underscore for non-nested paths” is misleading and has a typo. It’s about route segments when basePathValues=false.

-      // strip tailing underscore for non-nested paths
+      // strip trailing underscore for route segments (non-nested shorthand)

651-662: Micro-cleanup: avoid property existence checks on optional props.

in-operator is always true for optional keys; gate on actual prefix/suffix values.

-          if ('prefixSegment' in routeSegment) {
-            if (!baseValue.startsWith(prefix)) {
-              return false
-            }
-          }
-          if ('suffixSegment' in routeSegment) {
-            if (
-              !baseSegments[baseSegments.length - 1]?.value.endsWith(suffix)
-            ) {
-              return false
-            }
-          }
+          if (prefix && !baseValue.startsWith(prefix)) return false
+          if (suffix && !baseSegments[baseSegments.length - 1]?.value.endsWith(suffix)) return false
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d00f28 and 91705d6.

📒 Files selected for processing (58)
  • e2e/react-router/basic-file-based/src/routeTree.gen.ts (25 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/baz.$bazid.tsx (0 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/baz.tsx (0 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/baz_.$bazid.edit.tsx (0 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/suffix/route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.route.tsx (1 hunks)
  • e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix_.bar.tsx (1 hunks)
  • e2e/react-router/basic-file-based/tests/app.spec.ts (0 hunks)
  • e2e/react-router/basic-file-based/tests/non-nested-paths.spec.ts (1 hunks)
  • e2e/solid-router/basic-file-based/src/routeTree.gen.ts (25 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/baz.$bazid.tsx (0 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/baz.tsx (0 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/baz_.$bazid.edit.tsx (0 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.route.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix_.bar.tsx (1 hunks)
  • e2e/solid-router/basic-file-based/tests/app.spec.ts (0 hunks)
  • e2e/solid-router/basic-file-based/tests/non-nested-paths.spec.ts (1 hunks)
  • packages/router-core/src/path.ts (6 hunks)
  • packages/router-core/src/process-route-tree.ts (2 hunks)
  • packages/router-core/tests/match-by-path.test.ts (4 hunks)
  • packages/router-core/tests/path.test.ts (4 hunks)
💤 Files with no reviewable changes (8)
  • e2e/solid-router/basic-file-based/tests/app.spec.ts
  • e2e/react-router/basic-file-based/tests/app.spec.ts
  • e2e/react-router/basic-file-based/src/routes/non-nested/baz.tsx
  • e2e/react-router/basic-file-based/src/routes/non-nested/baz.$bazid.tsx
  • e2e/solid-router/basic-file-based/src/routes/non-nested/baz.tsx
  • e2e/solid-router/basic-file-based/src/routes/non-nested/baz.$bazid.tsx
  • e2e/react-router/basic-file-based/src/routes/non-nested/baz_.$bazid.edit.tsx
  • e2e/solid-router/basic-file-based/src/routes/non-nested/baz_.$bazid.edit.tsx
🧰 Additional context used
🧬 Code graph analysis (40)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/route.tsx (3)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.route.tsx (1)
e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/suffix/route.tsx (1)
e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix_.bar.tsx (3)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.route.tsx (3)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.foo.tsx (2)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
packages/router-core/src/process-route-tree.ts (1)
packages/router-core/src/path.ts (1)
  • parseRoutePathSegments (215-218)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx (3)
e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix_.bar.tsx (3)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.foo.tsx (4)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (4)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.index.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)
  • Route (3-5)
e2e/solid-router/basic-file-based/src/routes/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: Preview
  • GitHub Check: Test
🔇 Additional comments (50)
e2e/solid-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (2)

3-5: Route path correctly preserves base underscore (matches PR intent).

Using /non-nested/path/baz_/bar ensures the base segment’s underscore is preserved, aligning with the “don’t strip underscores from base segments” fix.

Please confirm there’s an e2e that navigates to /non-nested/path/baz_/bar and asserts both the heading and params output so this path specifically exercises the new parsing logic.


7-19: Solid params accessor usage is correct.

Route.useParams() returns an accessor; calling params() before JSON.stringify is the right pattern.

e2e/react-router/basic-file-based/src/routes/non-nested/path/baz_.bar.tsx (1)

3-5: LGTM: route wiring and params rendering look correct.
Matches the non‑nested path patterns and test IDs.

Also applies to: 7-19

e2e/react-router/basic-file-based/src/routes/non-nested/path/baz.route.tsx (1)

3-5: LGTM: layout route + Outlet are correctly set up.
No issues spotted.

Also applies to: 7-15

e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix_.bar.tsx (1)

3-5: LGTM.
Copy and test IDs consistent with non‑nested suffix bar.

Also applies to: 7-19

e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)

17-27: Confirm duplicate links are needed — no tests reference their test IDs.
Search for to-path-(foo|bar)-2 in e2e/solid-router returned only:

  • e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx:20,26 (the duplicate Link elements).
    No test files reference those testIDs.
    Remove duplicates, add tests that target them, or confirm the duplicates are intentional.
e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (1)

17-27: Duplicates confirmed — no change required. to-path-foo-2 and to-path-bar-2 appear in both e2e/react-router/basic-file-based/src/routes/non-nested/path/route.tsx (lines 20, 26) and e2e/solid-router/basic-file-based/src/routes/non-nested/path/route.tsx (lines 20, 26).

e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx (1)

1-19: Verified — no tests assert the exact heading text.
Only the route files contain the literal "Hello nested suffix index": e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx, e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.index.tsx.

e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx (1)

1-19: LGTM! Proper non-nested route implementation with underscore handling.

The route correctly implements the /non-nested/named/$baz_/bar path, demonstrating the PR's focus on proper underscore handling in non-nested paths. The component structure follows the established pattern with proper test IDs and parameter display.

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

15-26: Navigation structure expanded correctly.

The links properly navigate to the new non-nested route variants (named, prefix, suffix, path) that replace the previous baz-centric approach. The use of Route.fullPath and relative paths is consistent and correct.

e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix_.bar.tsx (1)

1-19: LGTM! Suffix pattern with underscore correctly implemented.

The route path /non-nested/suffix/{$baz}suffix_/bar properly demonstrates the suffix pattern with trailing underscore handling, which is central to this PR's underscore stripping fix.

e2e/solid-router/basic-file-based/src/routes/non-nested/named/route.tsx (1)

14-54: Comprehensive test coverage for underscore parameter variants.

The links test both regular (baz: 'baz') and underscore-containing (baz: 'baz_') parameters across different route variants. This directly validates the PR's fix for proper underscore handling in route segments vs. base segments.

e2e/react-router/basic-file-based/src/routes/non-nested/prefix/route.tsx (1)

14-54: Well-structured prefix route navigation with underscore parameter testing.

The component properly demonstrates prefix route patterns with both regular and underscore-containing parameters. The navigation structure validates the PR's core functionality for handling underscores in route segments.

e2e/solid-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)

1-16: LGTM! Clean layout route implementation.

The route correctly implements the prefix pattern layout with proper test ID and outlet structure for nested routes.

e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.route.tsx (1)

3-5: LGTM: route path and layout look correct for prefix param container.

  • Correct package import and Outlet usage.
  • Path string exercises the prefix+param shape used by the underscore fix.

Also applies to: 7-16

e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}_.bar.tsx (1)

3-5: LGTM: bar child renders params; good coverage of trailing underscore in base segment.

  • Using Route.useParams() is correct for React.
  • Test ids match the pattern used elsewhere.

Also applies to: 7-19

e2e/react-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.route.tsx (1)

3-5: LGTM: suffix container route matches intended {$param}suffix shape.

  • Import/source are correct; Outlet placed for nested children.

Also applies to: 7-16

e2e/react-router/basic-file-based/src/routes/non-nested/prefix/prefix{$baz}.foo.tsx (1)

3-5: LGTM: foo child uses typed params and stable test ids.

  • JSON.stringify(params) is fine for the E2E assertion style used here.

Also applies to: 7-20

e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.foo.tsx (1)

1-5: LGTM: Solid version correctly uses params() accessor.

  • Path and test ids align with React counterparts.

Also applies to: 7-20

packages/router-core/src/process-route-tree.ts (2)

6-9: Switch to parseRoutePathSegments here is correct and aligns with underscore semantics.

  • Sorting should parse route segments (not base values), so using parseRoutePathSegments on fullPath is appropriate.
  • Leading-slash stripping loop remains intact; no regressions spotted.

Also applies to: 72-81


1-11: No remaining production parsePathname usages — only tests call parsePathname.

Production code has been migrated to parseBasePathSegments / parseRoutePathSegments (e.g., packages/router-core/src/process-route-tree.ts:73 and multiple sites in packages/router-core/src/path.ts); the only direct parsePathname calls are in tests under packages/router-core/tests/* and its internal definition in packages/router-core/src/path.ts.

e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/{$baz}suffix.route.tsx (1)

3-5: LGTM: Solid suffix container mirrors React; good parity across frameworks.

Also applies to: 7-16

e2e/solid-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)

3-5: LGTM: named param container with Outlet is consistent and correct.

Also applies to: 7-16

e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx (1)

15-25: LGTM: clear nav to the four non-nested suites — verified

Confirmed e2e/react-router/basic-file-based/src/routes/non-nested/route.tsx links target ./named, ./prefix, ./suffix, and ./path and the corresponding child routes exist.

e2e/solid-router/basic-file-based/src/routes/non-nested/suffix/route.tsx (1)

1-58: LGTM: route wiring and links

Route layout, Link usage with Route.fullPath, params, and Outlet look correct.

e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz.route.tsx (1)

3-14: LGTM: route layout and Outlet

Matches test IDs and expected nesting; no issues.

packages/router-core/tests/path.test.ts (1)

341-356: Great additions covering underscore preservation.

New interpolatePath cases with trailing underscores and suffix params look good and align with the PR intent.

Also applies to: 527-532

packages/router-core/tests/match-by-path.test.ts (1)

23-33: LGTM: non-nested coverage is thorough.

The added underscore scenarios across default/case-insensitive/fuzzy paths look solid and reflect the intended behavior.

Also applies to: 110-126, 204-218, 219-229, 231-247, 252-266, 332-347, 349-359, 361-379, 381-391

packages/router-core/src/path.ts (1)

164-166: Nice: clear split between base vs route parsing.

Using parseBasePathSegments/parseRoutePathSegments here removes ambiguity and fixes the underscore regression.

If you have any external callers using parsePathname directly, confirm they don’t rely on the old underscore-trimming semantics. I can scan the repo with a script if helpful.

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

7-11: Generated file — no manual edits.

Types and wiring reflect the new non-nested families; looks consistent with source routes.

Also applies to: 574-592

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

41-44: Additions of non-nested route imports look correct and consistent.

New imports align with the new route families and referenced files; names match downstream usages.

Also applies to: 63-66, 73-76, 78-85


351-372: Dynamic child routes for named/prefix/path/suffix families — OK.

Curly-brace placeholders propagate correctly in ids/paths.


407-428: Index routes for dynamic children — OK.

Index child mapping to each dynamic segment is correct.


434-477: Sibling foo/bar routes for each family — OK.

“id” keeps file underscore markers; “path”/“fullPath” omit them as intended by the fix.


525-529: FileRoutesByFullPath unions updated completely.

New full paths cover base, dynamic, child, and index variants.

Also applies to: 543-547, 566-573, 575-578


600-604: FileRoutesByTo unions mirror navigation targets correctly.

Base routes point to WithChildren; dynamic paths map to their index targets.

Also applies to: 636-644, 646-649


674-678: FileRoutesById unions include underscored ids for non-nested markers.

Consistent with generator conventions; matches created constants.

Also applies to: 695-699, 718-726, 727-731


756-760: FileRouteTypes.fullPaths union extended correctly.

All new public paths are enumerated.

Also applies to: 774-778, 797-805, 806-810


831-835: FileRouteTypes.to union extended correctly.

Matches FileRoutesByTo additions.

Also applies to: 867-875, 876-880


904-908: FileRouteTypes.id union extended correctly.

Underscored ids captured as expected.

Also applies to: 925-929, 948-956, 957-961


1201-1228: Module augmentation entries for new routes — OK.

preLoaderRoute/parentRoute/path/fullPath are coherent across base, dynamic, index, and child routes.

Please ensure the React e2e routeTree.gen.ts received the same expansions to keep cross-framework parity.

Also applies to: 1355-1382, 1425-1452, 1460-1515


1561-1589: NonNestedNamed: children + WithChildren wiring — OK.


1590-1604: NonNestedPathBaz: children + WithChildren wiring — OK.


1605-1617: NonNestedPath: children + WithChildren wiring — OK.


1618-1635: NonNestedPrefix{$baz}: children + WithChildren wiring — OK.


1636-1650: NonNestedPrefix: children + WithChildren wiring — OK.


1651-1668: NonNested{$baz}suffix: children + WithChildren wiring — OK.


1669-1683: NonNestedSuffix: children + WithChildren wiring — OK.


1685-1696: /non-nested aggregate children registered — OK.

All four families are present under NonNestedRouteRoute.

Also applies to: 1698-1700


235-254: Approve: Top-level NonNested route family nodes are wired correctly under /non-nested.

Verification: fullPath values contain no underscores; id values include the expected underscores (examples in e2e/solid-router/basic-file-based/src/routeTree.gen.ts at lines 1461, 1475, 1489, 1503).

@nlynzaad nlynzaad changed the title fix(router-core): Non nested paths - only strip underscore on route segments fix(router-core): Non nested paths - only strip trailing underscore on route segments Sep 22, 2025
@nlynzaad nlynzaad merged commit ecd79d2 into main Sep 22, 2025
6 checks passed
@nlynzaad nlynzaad deleted the non-nested-paths branch September 22, 2025 01:12
nlynzaad added a commit that referenced this pull request Sep 22, 2025
nlynzaad added a commit that referenced this pull request Sep 22, 2025
…n route segments - alpha (#5183)

PR to merge #5182 with alpha
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.

1 participant