Skip to content

Conversation

@schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Jan 4, 2026

Summary by CodeRabbit

  • New Features

    • Simplified syntax to merge physical routes at the current level using a single-argument physical() call.
  • Documentation

    • Added guide showing how to merge physical routes without a path prefix, with examples and conflict warnings.
  • Improvements

    • More detailed, actionable warnings when route exports are missing (includes suggested ignore guidance and config context).
  • Tests

    • Expanded test coverage for merging behavior and conflict detection, including new snapshot scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

📝 Walkthrough

Walkthrough

Adds a single-argument overload for physical() to mount a directory at the current level (empty path prefix), documents the behavior, enhances a generator warning message, and adds multiple tests and snapshots covering merge and conflict scenarios.

Changes

Cohort / File(s) Summary
Documentation
docs/router/framework/react/routing/virtual-file-routes.md
Inserted a "Merging Physical Routes at Current Level" subsection (duplicated in two locations) describing physical('dir') / physical('', 'dir'), examples, and conflict warnings.
API (virtual-file-routes)
packages/virtual-file-routes/src/api.ts
Added overloads for physical(directory: string) and physical(pathPrefix: string, directory: string) and updated implementation to handle single- and two-argument invocations (preserves existing behavior).
Generator (warnings)
packages/router-generator/src/generator.ts
Replaced a terse "no-route-export" warning with a detailed, configurable warning that computes a suggested ignore file/path, shows current config values, and gives explicit exclusion guidance; behavior still returns null after warning.
Test harness
packages/router-generator/tests/generator.test.ts
Added new test branches for virtual/physical empty-path merge and conflicts (virtual-physical-empty-path-merge, virtual-physical-empty-path-conflict-root, virtual-physical-empty-path-conflict-virtual, virtual-physical-no-prefix) and extended shouldThrow expectations for conflict messages.
Tests: empty-path merge
packages/router-generator/tests/generator/virtual-physical-empty-path-merge/*
New test config, root route, virtual /about, merged merged/* (/contact, /index), and generated routeTree.snapshot.ts for empty-path physical merge scenario.
Tests: single-arg physical (no prefix)
packages/router-generator/tests/generator/virtual-physical-no-prefix/*
New test config, root route, virtual /about, merged merged/* (/contact, /index), and generated routeTree.snapshot.ts demonstrating physical('merged') single-arg behavior.
Tests: root conflict
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/*
New test config and files: virtual root __root.tsx, physical merged/route.tsx (createFileRoute('')) and merged/index.tsx to assert duplicate-root conflict detection.
Tests: virtual vs physical conflict
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/*
New test config and files: virtual /about route and physical merged/about.tsx to assert collision detection for the same resolved path.

Sequence Diagram(s)

(omitted — changes are API/tests/docs and do not introduce a multi-component sequential control flow requiring a diagram)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • nlynzaad

Poem

🐰 I sniffed the paths and found a seam,

physical('merged') joins like a dream.
Docs updated, tests now sing,
Warnings clearer — hop, joy to bring! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
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.
Title check ❓ Inconclusive The title 'fix: generator improvements' is vague and generic, using non-descriptive terms that don't clearly convey the specific main change from the changeset. Use a more specific title that describes the primary feature or fix, such as 'feat: support empty-path physical route merging' or 'fix: improve generator warning messages for physical routes'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

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

@nx-cloud
Copy link

nx-cloud bot commented Jan 4, 2026

View your CI Pipeline Execution ↗ for commit a7a226f

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 8m 45s View ↗

☁️ Nx Cloud last updated this comment at 2026-01-04 17:38:09 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 4, 2026

More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6296

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6296

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6296

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: a7a226f

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

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f19b51e and d2637ac.

📒 Files selected for processing (29)
  • docs/router/framework/react/routing/virtual-file-routes.md
  • packages/router-generator/src/generator.ts
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json
  • packages/virtual-file-routes/src/api.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/src/generator.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
  • packages/router-generator/tests/generator.test.ts
  • packages/virtual-file-routes/src/api.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/src/generator.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
  • packages/router-generator/tests/generator.test.ts
  • packages/virtual-file-routes/src/api.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

Use relative links to docs/ folder format (e.g., ./guide/data-loading) for internal documentation references

Files:

  • docs/router/framework/react/routing/virtual-file-routes.md
🧠 Learnings (10)
📓 Common learnings
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.
Learnt from: schiller-manuel
Repo: TanStack/router PR: 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.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/src/generator.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
  • docs/router/framework/react/routing/virtual-file-routes.md
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
  • docs/router/framework/react/routing/virtual-file-routes.md
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 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:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/src/generator.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/src/generator.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • docs/router/framework/react/routing/virtual-file-routes.md
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
📚 Learning: 2025-12-17T02:17:47.423Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:47.423Z
Learning: In packages/router-generator/src/generator.ts, enforce that pathless_layout routes with a cleanedPath must have a path property. This is required because child routes inherit the parent's path; without a path property, the full path will not resolve correctly at runtime. Update the route type/validation to require path for such routes and add tests ensuring that a pathless_layout with cleanedPath provides a valid fullPath resolution.

Applied to files:

  • packages/router-generator/src/generator.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx
  • docs/router/framework/react/routing/virtual-file-routes.md
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx
  • packages/router-generator/tests/generator.test.ts
  • packages/virtual-file-routes/src/api.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
📚 Learning: 2025-10-14T18:59:33.990Z
Learnt from: FatahChan
Repo: TanStack/router PR: 5475
File: e2e/react-start/basic-prerendering/src/routes/redirect/$target/via-beforeLoad.tsx:8-0
Timestamp: 2025-10-14T18:59:33.990Z
Learning: In TanStack Router e2e test files, when a route parameter is validated at the route level (e.g., using zod in validateSearch or param validation), switch statements on that parameter do not require a default case, as the validation ensures only expected values will reach the switch.

Applied to files:

  • packages/router-generator/tests/generator.test.ts
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts
🧬 Code graph analysis (11)
packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx (2)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx (1)
  • Route (4-6)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts (1)
packages/virtual-file-routes/src/api.ts (3)
  • rootRoute (10-19)
  • route (66-84)
  • physical (100-118)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx (1)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx (1)
  • Route (4-6)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx (2)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx (2)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts (1)
packages/virtual-file-routes/src/api.ts (3)
  • rootRoute (10-19)
  • route (66-84)
  • physical (100-118)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx (1)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx (1)
  • Route (4-6)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts (4)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts (1)
  • routes (5-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts (1)
  • routes (5-8)
packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts (1)
  • routes (3-8)
packages/virtual-file-routes/src/api.ts (3)
  • rootRoute (10-19)
  • route (66-84)
  • physical (100-118)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx (4)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx (1)
  • Route (2-2)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx (3)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts (4)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts (1)
  • routes (5-8)
packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts (1)
  • routes (3-8)
packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts (1)
  • routes (5-8)
packages/virtual-file-routes/src/api.ts (2)
  • rootRoute (10-19)
  • physical (100-118)
🪛 markdownlint-cli2 (0.18.1)
docs/router/framework/react/routing/virtual-file-routes.md

233-233: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ 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 (29)
packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/about.tsx (1)

1-2: LGTM! Minimal route definition for testing.

The route definition is valid. The absence of a component is acceptable for test fixtures that focus on route structure rather than rendering behavior.

packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/index.tsx (1)

1-2: LGTM! Index route for merge testing.

The route definition correctly uses '/' for an index route. In the context of virtual-physical empty-path merging, the generator will handle path resolution appropriately.

packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/__root.tsx (1)

1-5: LGTM! Complete root route implementation.

The root route is properly implemented with all necessary imports and a standard component that renders an Outlet for child routes.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/__root.tsx (1)

1-5: LGTM! Complete root route implementation.

The root route is properly implemented with all necessary imports and follows the standard pattern for test fixtures in this suite.

packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/merged/contact.tsx (1)

1-2: LGTM! Clean test fixture for route merging.

This test file correctly defines a /contact route using the standard TanStack Router pattern. It will help verify that physical directory merging works as expected in the test scenario.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/index.tsx (1)

1-5: LGTM! Appropriate test fixture for conflict scenarios.

This index route correctly creates a root-level route that will be used to test conflict detection when merging physical directories at the root level. The simple component implementation is appropriate for testing purposes.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/index.tsx (1)

1-5: LGTM! Consistent test fixture for virtual conflict testing.

This test fixture follows the same pattern as the root conflict scenario and correctly sets up a route to test conflict detection between virtual and physical routes. The implementation is clean and appropriate for its testing purpose.

packages/router-generator/src/generator.ts (1)

1093-1108: Excellent improvement to developer experience!

The enhanced warning message is much more helpful than the previous version. It provides:

  • Clear identification of the problematic file
  • Two concrete options for excluding the file
  • Current configuration values for reference
  • Specific suggested filename with the ignore prefix

The implementation uses path.basename, path.dirname, and path.join correctly for cross-platform compatibility. This will significantly reduce confusion when developers have non-route files in their routes directory.

packages/virtual-file-routes/src/api.ts (1)

86-117: Well-implemented function overloading with clear documentation!

This enhancement elegantly adds support for single-argument usage while maintaining backward compatibility. The implementation correctly:

  • Provides clear JSDoc for both overload variants
  • Uses the presence/absence of the second parameter to distinguish between cases
  • Sets pathPrefix: '' for single-argument calls (merging at current level)
  • Preserves the original two-argument behavior
  • Maintains type safety through proper overload signatures

The single-argument form physical('dir') is a nice convenience for the common case of merging routes at the current level, which aligns perfectly with the PR objectives.

packages/router-generator/tests/generator/virtual-physical-no-prefix/routes.ts (1)

1-8: LGTM!

This test file correctly exercises the new single-argument physical() overload that merges physical routes at the current level (with an empty path prefix). The structure follows the established pattern seen in related test fixtures, and the inline comments clearly document the test's intent.

packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routeTree.snapshot.ts (1)

1-95: Snapshot file - no review needed.

Based on learnings, test snapshot files in the router-generator tests directory are fixtures used to verify the generator's output and should be preserved as-is.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/tsr.config.json (1)

1-5: LGTM!

Standard test configuration file with appropriate paths for the virtual-physical conflict scenario.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/__root.tsx (1)

1-5: LGTM!

Minimal root route fixture following the established pattern for test scenarios. The createRootRoute usage with an Outlet component is correct and idiomatic.

packages/router-generator/tests/generator/virtual-physical-empty-path-merge/tsr.config.json (1)

1-5: LGTM!

Standard test configuration for the virtual-physical empty path merge scenario.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/tsr.config.json (1)

1-5: LGTM!

Standard test configuration for the virtual-physical empty path root conflict scenario.

packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/contact.tsx (1)

1-5: LGTM!

This route file follows the established pattern for file-based routes in the test fixtures. The createFileRoute('/contact') usage is consistent with sibling routes (about.tsx, index.tsx) in the same test directory.

packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/merged/index.tsx (1)

1-5: LGTM! Test fixture correctly defines index route.

The file follows TanStack Router conventions for file-based routing. The index route at '/' with a minimal component is appropriate for testing the virtual-physical merge scenario.

packages/router-generator/tests/generator/virtual-physical-no-prefix/routes/about.tsx (1)

1-5: LGTM! Test fixture correctly defines about route.

The route definition follows framework conventions. The '/about' route with a minimal component is appropriate for testing virtual-physical routing scenarios without prefix conflicts.

packages/router-generator/tests/generator/virtual-physical-no-prefix/tsr.config.json (1)

1-5: LGTM! Test configuration is properly structured.

The configuration correctly specifies the routes directory, generated route tree output, and virtual route config file paths for the no-prefix merge test scenario.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/about.tsx (1)

1-6: LGTM! Conflict test fixture is correctly designed.

The virtual route intentionally conflicts with the physical route at merged/about.tsx to test the generator's conflict detection capabilities. The comment clearly documents this, and the "(virtual)" label in the component helps distinguish between the two routes during testing.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx (1)

1-5: LGTM! Root conflict test fixture is correctly designed.

The physical root route (defined with empty string path) intentionally conflicts with the virtual __root.tsx to test the generator's ability to detect conflicting root routes. The comments clearly document this test scenario.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes.ts (1)

1-5: LGTM! Clear test case for root-level conflict detection.

This test fixture correctly sets up a scenario where a physical directory containing __root.tsx is mounted at the root level, creating a conflict with the virtual root. The comment clearly explains the expected behavior.

docs/router/framework/react/routing/virtual-file-routes.md (1)

227-263: Excellent documentation for the new merging feature.

The section clearly explains the merging behavior, provides practical examples, and appropriately warns users about potential conflicts. The code examples demonstrate both the single-argument and two-argument forms of the physical() API.

packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes.ts (1)

1-8: LGTM! Clear test case for successful merge scenario.

This test fixture correctly demonstrates the happy path where physical routes are merged at the root level without conflicts. The inline comments effectively explain the intended behavior.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes/merged/about.tsx (1)

1-6: LGTM! Well-structured test fixture for conflict detection.

This physical route definition correctly sets up a conflict scenario with a virtual route at the same path. The component text clearly distinguishes it as the physical version for test verification purposes.

packages/router-generator/tests/generator.test.ts (2)

107-118: LGTM! Test configurations properly set up for new scenarios.

The four new test case branches correctly configure the virtual route system for testing physical route merging and conflict detection. Each scenario appropriately points to its respective ./routes.ts configuration file.


258-263: LGTM! Clear error messages for conflict scenarios.

The expected error messages correctly identify the conflicting route paths for both the root-level conflict and the virtual route conflict. The format is consistent with the existing duplicate-fullPath error message pattern.

packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-virtual/routes.ts (1)

1-8: Well-structured conflict test case.

The test clearly documents its purpose and correctly uses the physical('', 'merged') API to trigger a conflict between the virtual /about route and the physical merged/about.tsx that would resolve to the same path.

packages/router-generator/tests/generator/virtual-physical-no-prefix/routeTree.snapshot.ts (1)

1-95: Snapshot file acknowledged.

Based on learnings, this is a test snapshot fixture used to verify the generator's output for the virtual-physical-no-prefix scenario. The generated route tree correctly reflects three routes (/, /about, /contact) merged from physical routes without a path prefix.

Comment on lines +233 to +241
```
/routes
├── __root.tsx
├── about.tsx
└── features
├── index.tsx
└── contact.tsx
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Specify language identifier for fenced code block.

The fenced code block showing the file structure should have a language identifier for better rendering and accessibility.

🔎 Proposed fix
-```
+```text
 /routes
 ├── __root.tsx
 ├── about.tsx
 └── features
     ├── index.tsx
     └── contact.tsx

</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

233-233: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In docs/router/framework/react/routing/virtual-file-routes.md around lines 233
to 241, the fenced code block showing the file structure lacks a language
identifier; update the opening fence to include a language (e.g., use ```text)
so the block is rendered correctly and improves accessibility/semantics in docs.


</details>

<!-- fingerprinting:phantom:poseidon:puma -->

<!-- This is an auto-generated comment by CodeRabbit -->

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 (1)
packages/router-generator/src/generator.ts (1)

1093-1108: Enhanced warning message improves developer experience.

The detailed warning with configuration guidance and suggested fixes is a valuable improvement. The routeFileIgnorePrefix property has a guaranteed default value of '-' defined in the config schema, so there is no risk of undefined values appearing in the suggested file name. The code is correct and safe.

Consider using a single template literal for the message construction for improved readability:

-        let message = `Warning: Route file "${node.fullPath}" does not export a Route. This file will not be included in the route tree.`
-        message += `\n\nIf this file is not intended to be a route, you can exclude it using one of these options:`
-        message += `\n  1. Rename the file to "${suggestedFullPath}" (prefix with "${ignorePrefix}")`
-        message += `\n  2. Use 'routeFileIgnorePattern' in your config to match this file`
-        message += `\n\nCurrent configuration:`
-        message += `\n  routeFileIgnorePrefix: "${ignorePrefix}"`
-        message += `\n  routeFileIgnorePattern: ${ignorePattern ? `"${ignorePattern}"` : 'undefined'}`
+        const message = `Warning: Route file "${node.fullPath}" does not export a Route. This file will not be included in the route tree.
+
+If this file is not intended to be a route, you can exclude it using one of these options:
+  1. Rename the file to "${suggestedFullPath}" (prefix with "${ignorePrefix}")
+  2. Use 'routeFileIgnorePattern' in your config to match this file
+
+Current configuration:
+  routeFileIgnorePrefix: "${ignorePrefix}"
+  routeFileIgnorePattern: ${ignorePattern ? `"${ignorePattern}"` : 'undefined'}`
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2637ac and a7a226f.

📒 Files selected for processing (3)
  • packages/router-generator/src/generator.ts
  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/router-generator/tests/generator/virtual-physical-empty-path-merge/routes/__root.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/src/generator.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/src/generator.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.
Learnt from: schiller-manuel
Repo: TanStack/router PR: 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.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/src/generator.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 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:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/src/generator.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
  • packages/router-generator/src/generator.ts
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions

Applied to files:

  • packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx
📚 Learning: 2025-12-17T02:17:47.423Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:47.423Z
Learning: In packages/router-generator/src/generator.ts, enforce that pathless_layout routes with a cleanedPath must have a path property. This is required because child routes inherit the parent's path; without a path property, the full path will not resolve correctly at runtime. Update the route type/validation to require path for such routes and add tests ensuring that a pathless_layout with cleanedPath provides a valid fullPath resolution.

Applied to files:

  • packages/router-generator/src/generator.ts
⏰ 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 (1)
packages/router-generator/tests/generator/virtual-physical-empty-path-conflict-root/routes/merged/route.tsx (1)

1-5: LGTM! Test fixture correctly implements the conflict scenario.

This test fixture properly creates a root-level route using an empty string path to test conflict detection with virtual root routes. The comment clearly documents the intentional conflict scenario.

@schiller-manuel schiller-manuel merged commit 71fc7a6 into main Jan 4, 2026
7 of 8 checks passed
@schiller-manuel schiller-manuel deleted the generator-improvements branch January 4, 2026 17:40
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.

2 participants