Skip to content

Conversation

schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Oct 6, 2025

fixes #5388

Summary by CodeRabbit

  • New Features
    • Added an end-to-end example app demonstrating React routing with a base path (/app/) built with Vite and TanStack Router; includes a typed, file-based route tree and page components (Home, About).
  • Bug Fixes
    • Fixed full-page reload navigation to correctly resolve URLs under a base path when reloadDocument is enabled.
  • Tests
    • Added Playwright E2E tests covering navigation with base path and global test setup/teardown.
  • Chores
    • Added .gitignore rules and project tooling/configuration (package.json, TypeScript, Vite, Playwright).

Copy link
Contributor

coderabbitai bot commented Oct 6, 2025

Walkthrough

Adds a new e2e React Router project with basepath support (Vite + Playwright), generated file-based routes and tests, global test server setup/teardown, and adjusts RouterCore.navigate to use the router-built location's url when performing reloadDocument-driven navigations.

Changes

Cohort / File(s) Summary
E2E project scaffold
e2e/react-router/basepath-file-based/.gitignore, e2e/react-router/basepath-file-based/index.html, e2e/react-router/basepath-file-based/package.json, e2e/react-router/basepath-file-based/tsconfig.json, e2e/react-router/basepath-file-based/vite.config.js
Add project files: ignore rules, HTML entry, package manifest & scripts, TypeScript config, and Vite config with base '/app/' and Router + React plugins.
Playwright configuration
e2e/react-router/basepath-file-based/playwright.config.ts
New Playwright config using dynamic ports, computed baseURL, single Chromium project, webServer build/serve steps, and global setup/teardown.
App source & routes
e2e/react-router/basepath-file-based/src/main.tsx, e2e/react-router/basepath-file-based/src/routeTree.gen.ts, e2e/react-router/basepath-file-based/src/routes/*
Add React entry mounting RouterProvider with basepath, generated typed file-based route tree for / and /about, and file-based route components (index, about, root).
E2E tests
e2e/react-router/basepath-file-based/tests/reload-document.test.ts
Add Playwright test that verifies navigation respects basepath when reloadDocument: true (checks /app/ ↔ /app/about).
Test lifecycle
e2e/react-router/basepath-file-based/tests/setup/global.setup.ts, e2e/react-router/basepath-file-based/tests/setup/global.teardown.ts
Add global setup/teardown to start/stop a dummy server using router-e2e-utils keyed by package name.
Core router change
packages/router-core/src/router.ts
In RouterCore.navigate when reloadDocument = true and no explicit href, derive the navigation target from location.url (router-built url) instead of location.href.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant App as App (Router UI)
  participant Router as RouterCore
  participant Loc as BuildLocation
  participant Win as window.location

  User->>App: Click nav with reloadDocument:true
  App->>Router: navigate({ to, reloadDocument: true })
  Router->>Loc: buildLocation(to, opts)
  Note right of Loc: buildLocation includes basepath
  Loc-->>Router: { url, href, ... }
  alt reloadDocument && no explicit href
    Router->>Win: assign( url )  %% changed from href to url
  else
    Router->>Win: assign( provided href or existing href )
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I hop along the basepath trail, so quick and spry,
Reloads now follow the URL that's built nearby.
From /app/ to /about I bounce with glee,
No lost routes, no wrong turns — just carrot victory. 🥕

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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title directly references the change to the navigate() function and the reloadDocument flag, which is the core code modification in this PR, and it accurately indicates that navigation behavior has been fixed under reloadDocument=true. Although it does not explicitly mention basepath, it is still closely related to the main change and clearly informs reviewers about the function and flag involved.
Linked Issues Check ✅ Passed The PR implements the fix in RouterCore.navigate to derive the correct href so that reloadDocument navigations include the configured basepath, and it provides end-to-end tests that verify navigation from “/app” to “/app/about” and back. These changes directly address the bug described in issue #5388 and confirm the expected behavior under a basepath.
Out of Scope Changes Check ✅ Passed All added files and modifications are scoped to the router-core navigate logic or the accompanying end-to-end test harness for verifying basepath behavior, and there are no unrelated changes outside these objectives.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-5388

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

Copy link

nx-cloud bot commented Oct 6, 2025

View your CI Pipeline Execution ↗ for commit b097f19

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

☁️ Nx Cloud last updated this comment at 2025-10-06 21:17:36 UTC

Copy link

pkg-pr-new bot commented Oct 6, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/zod-adapter

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

commit: b097f19

@schiller-manuel schiller-manuel changed the title fix: navigate() respects basepath for when reloadDocument=true fix: navigate() respects rewrites for when reloadDocument=true Oct 6, 2025
@schiller-manuel schiller-manuel changed the title fix: navigate() respects rewrites for when reloadDocument=true fix: navigate() respects rewrites when reloadDocument=true Oct 6, 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: 0

♻️ Duplicate comments (2)
e2e/react-router/basepath-file-based/tests/setup/global.setup.ts (1)

2-2: Verify import assertion syntax compatibility.

Same as the teardown file: the with { type: 'json' } syntax requires Node.js 17.1+ or 16.14+ and TypeScript 4.5+. Ensure runtime compatibility.

e2e/react-router/basepath-file-based/playwright.config.ts (1)

6-6: Verify import assertion syntax compatibility.

The with { type: 'json' } syntax requires Node.js 17.1+ or 16.14+ and TypeScript 4.5+. This is consistent with other files in this e2e project.

🧹 Nitpick comments (1)
e2e/react-router/basepath-file-based/src/main.tsx (1)

22-22: Consider defensive check for root element.

The non-null assertion assumes the element exists. While this is safe in a controlled e2e environment, a defensive check with an error message would improve robustness.

Apply this diff for safer handling:

-const rootElement = document.getElementById('app')!
+const rootElement = document.getElementById('app')
+if (!rootElement) {
+  throw new Error('Root element not found')
+}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9f2313 and 184216e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • e2e/react-router/basepath-file-based/.gitignore (1 hunks)
  • e2e/react-router/basepath-file-based/index.html (1 hunks)
  • e2e/react-router/basepath-file-based/package.json (1 hunks)
  • e2e/react-router/basepath-file-based/playwright.config.ts (1 hunks)
  • e2e/react-router/basepath-file-based/src/main.tsx (1 hunks)
  • e2e/react-router/basepath-file-based/src/routeTree.gen.ts (1 hunks)
  • e2e/react-router/basepath-file-based/tests/reload-document.test.ts (1 hunks)
  • e2e/react-router/basepath-file-based/tests/setup/global.setup.ts (1 hunks)
  • e2e/react-router/basepath-file-based/tests/setup/global.teardown.ts (1 hunks)
  • e2e/react-router/basepath-file-based/tsconfig.json (1 hunks)
  • e2e/react-router/basepath-file-based/vite.config.js (1 hunks)
  • packages/router-core/src/router.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • e2e/react-router/basepath-file-based/playwright.config.ts
  • e2e/react-router/basepath-file-based/src/main.tsx
  • e2e/react-router/basepath-file-based/tests/reload-document.test.ts
  • e2e/react-router/basepath-file-based/src/routeTree.gen.ts
  • packages/router-core/src/router.ts
  • e2e/react-router/basepath-file-based/tests/setup/global.setup.ts
  • e2e/react-router/basepath-file-based/tests/setup/global.teardown.ts
e2e/**

📄 CodeRabbit inference engine (AGENTS.md)

Store end-to-end tests under the e2e/ directory

Files:

  • e2e/react-router/basepath-file-based/playwright.config.ts
  • e2e/react-router/basepath-file-based/src/main.tsx
  • e2e/react-router/basepath-file-based/tests/reload-document.test.ts
  • e2e/react-router/basepath-file-based/src/routeTree.gen.ts
  • e2e/react-router/basepath-file-based/tests/setup/global.setup.ts
  • e2e/react-router/basepath-file-based/tsconfig.json
  • e2e/react-router/basepath-file-based/index.html
  • e2e/react-router/basepath-file-based/package.json
  • e2e/react-router/basepath-file-based/tests/setup/global.teardown.ts
  • e2e/react-router/basepath-file-based/vite.config.js
packages/router-core/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep framework-agnostic core router logic in packages/router-core/

Files:

  • packages/router-core/src/router.ts
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

Use workspace:* protocol for internal dependencies in package.json files

Files:

  • e2e/react-router/basepath-file-based/package.json
🧠 Learnings (2)
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
PR: TanStack/router#5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.

Applied to files:

  • e2e/react-router/basepath-file-based/src/routeTree.gen.ts
📚 Learning: 2025-10-01T18:30:26.591Z
Learnt from: schiller-manuel
PR: TanStack/router#5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.

Applied to files:

  • packages/router-core/src/router.ts
🧬 Code graph analysis (6)
e2e/react-router/basepath-file-based/playwright.config.ts (1)
scripts/set-ts-version.js (1)
  • packageJson (33-33)
e2e/react-router/basepath-file-based/src/main.tsx (2)
packages/router-core/src/router.ts (1)
  • Register (97-102)
e2e/react-router/js-only-file-based/src/main.jsx (2)
  • rootElement (15-15)
  • root (18-18)
e2e/react-router/basepath-file-based/src/routeTree.gen.ts (1)
e2e/react-router/js-only-file-based/src/routeTree.gen.js (2)
  • IndexRoute (30-34)
  • rootRouteChildren (90-94)
packages/router-core/src/router.ts (1)
packages/history/src/index.ts (1)
  • location (162-164)
e2e/react-router/basepath-file-based/tests/setup/global.setup.ts (4)
e2e/react-router/basic/tests/setup/global.setup.ts (1)
  • setup (4-6)
e2e/react-router/basic-virtual-file-based/tests/setup/global.setup.ts (1)
  • setup (4-6)
e2e/react-router/js-only-file-based/tests/setup/global.setup.ts (1)
  • setup (4-6)
e2e/solid-router/basic-file-based/tests/setup/global.setup.ts (1)
  • setup (4-6)
e2e/react-router/basepath-file-based/tests/setup/global.teardown.ts (2)
scripts/set-ts-version.js (1)
  • packageJson (33-33)
e2e/solid-router/basic-file-based/tests/setup/global.teardown.ts (1)
  • teardown (4-6)
⏰ 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 (10)
packages/router-core/src/router.ts (1)

1919-1924: Reload navigations now honor basepath rewrites

Using location.url here ensures we send the rewritten, basepath-aware absolute URL to window.location, so reloadDocument navigations keep the configured basepath. This directly addresses the regression from #5388.

e2e/react-router/basepath-file-based/index.html (1)

1-11: LGTM!

Standard HTML5 boilerplate for a Vite + React application. The structure is clean and appropriate for the e2e test setup.

e2e/react-router/basepath-file-based/tsconfig.json (1)

1-15: LGTM!

The TypeScript configuration is appropriate for a Vite-based e2e test project. Strict mode is enabled as per coding guidelines, and the settings align with modern React development practices.

e2e/react-router/basepath-file-based/src/main.tsx (1)

7-13: LGTM!

The router configuration with basepath: '/app' correctly aligns with the test objectives to verify basepath handling with reloadDocument: true.

e2e/react-router/basepath-file-based/tests/reload-document.test.ts (1)

3-18: LGTM!

The test effectively validates the PR objective: ensuring that navigate() respects the basepath when reloadDocument=true. The test flow is clear and uses appropriate Playwright patterns for navigation and assertions.

e2e/react-router/basepath-file-based/tests/setup/global.teardown.ts (2)

4-6: LGTM!

The teardown function correctly stops the dummy server using the package name, following the standard pattern used in other e2e projects.


2-2: Import assertion syntax is compatible. Node.js v24.3.0 and TypeScript v5.9.0 satisfy the JSON import assertion requirements.

e2e/react-router/basepath-file-based/tests/setup/global.setup.ts (1)

4-6: LGTM!

The setup function correctly starts the dummy server, mirroring the pattern used across other e2e test projects in the repository.

e2e/react-router/basepath-file-based/playwright.config.ts (2)

8-9: Top-level await usage is appropriate.

Top-level await for retrieving dynamic ports is a clean approach and is well-supported in modern Node.js versions (14.8+) with ES modules.


14-41: LGTM!

The Playwright configuration is comprehensive and follows best practices:

  • Single worker prevents concurrency issues in e2e tests
  • Global setup/teardown hooks for server lifecycle management
  • Reuses existing server outside CI for faster local development
  • Chromium-only testing is appropriate for this e2e scenario

@schiller-manuel schiller-manuel merged commit 2db746c into main Oct 6, 2025
5 of 6 checks passed
@schiller-manuel schiller-manuel deleted the fix-5388 branch October 6, 2025 21:19
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 (2)
e2e/react-router/basepath-file-based/src/routes/index.tsx (1)

1-25: LGTM! Navigation logic correctly implements the test scenario.

The route definition and navigation with reloadDocument: true properly exercises the basepath behavior that this PR fixes.

Optional enhancement: Consider adding type="button" to the button element for better HTML semantics:

       <button
+        type="button"
         data-testid="to-about-btn"
         onClick={() =>
e2e/react-router/basepath-file-based/src/routes/about.tsx (1)

1-20: LGTM! Completes the bidirectional navigation test.

The about route correctly mirrors the home route pattern, enabling complete testing of basepath behavior with reloadDocument in both directions.

Optional enhancement: Consider adding type="button" to the button element for better HTML semantics:

       <button
+        type="button"
         onClick={() => navigate({ to: '/', reloadDocument: true })}
         data-testid="to-home-btn"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 184216e and b097f19.

📒 Files selected for processing (3)
  • e2e/react-router/basepath-file-based/src/routes/__root.tsx (1 hunks)
  • e2e/react-router/basepath-file-based/src/routes/about.tsx (1 hunks)
  • e2e/react-router/basepath-file-based/src/routes/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • e2e/react-router/basepath-file-based/src/routes/__root.tsx
  • e2e/react-router/basepath-file-based/src/routes/index.tsx
  • e2e/react-router/basepath-file-based/src/routes/about.tsx
**/src/routes/**

📄 CodeRabbit inference engine (AGENTS.md)

Place file-based routes under src/routes/ directories

Files:

  • e2e/react-router/basepath-file-based/src/routes/__root.tsx
  • e2e/react-router/basepath-file-based/src/routes/index.tsx
  • e2e/react-router/basepath-file-based/src/routes/about.tsx
e2e/**

📄 CodeRabbit inference engine (AGENTS.md)

Store end-to-end tests under the e2e/ directory

Files:

  • e2e/react-router/basepath-file-based/src/routes/__root.tsx
  • e2e/react-router/basepath-file-based/src/routes/index.tsx
  • e2e/react-router/basepath-file-based/src/routes/about.tsx
🧬 Code graph analysis (3)
e2e/react-router/basepath-file-based/src/routes/__root.tsx (2)
e2e/react-router/basepath-file-based/src/routes/about.tsx (1)
  • Route (3-5)
e2e/react-router/basepath-file-based/src/routes/index.tsx (1)
  • Route (3-5)
e2e/react-router/basepath-file-based/src/routes/index.tsx (2)
e2e/react-router/basepath-file-based/src/routes/__root.tsx (1)
  • Route (3-3)
e2e/react-router/basepath-file-based/src/routes/about.tsx (1)
  • Route (3-5)
e2e/react-router/basepath-file-based/src/routes/about.tsx (2)
e2e/react-router/basepath-file-based/src/routes/__root.tsx (1)
  • Route (3-3)
e2e/react-router/basepath-file-based/src/routes/index.tsx (1)
  • Route (3-5)
🔇 Additional comments (1)
e2e/react-router/basepath-file-based/src/routes/__root.tsx (1)

1-3: LGTM! Clean root route implementation.

The minimal root route correctly establishes the foundation for the file-based routing structure used in the e2e tests.

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.

Navigating with reloadDocument: true broken with basepath in RC
1 participant