Skip to content

Conversation

@jxom
Copy link

@jxom jxom commented Dec 17, 2025

Enables #3861.

Enhances the Route Generator plugin interface to allow for plugin-driven route generation. Can see a reference implementation of an MDX routegen plugin.

Motivation: I want to rewrite Vocs to be powered by TanStack Router. :D

Summary by CodeRabbit

  • New Features

    • Extended plugin API with hooks to transform route nodes, detect built-in files, and inject extra route-tree content
    • Route nodes can carry metadata for custom component imports, extensions, skip-transform flags, and per-node templates
    • Added MDX route generator plugin to support MDX-based file routes
  • Bug Fixes / Behavior

    • Improved import path, export name, and extension handling for file and Vue components
    • Split external vs. virtual route handling to ensure correct import/template selection
  • Tests

    • Added MDX and Vue route generator test suites and snapshots

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

Warning

Rate limit exceeded

@jxom has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 19 minutes and 12 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between da28d98 and d5ea6a9.

📒 Files selected for processing (1)
  • packages/router-generator/tests/plugins/mdx.ts (1 hunks)

Walkthrough

Adds a plugin transform phase to route-node collection, extends RouteNode metadata and plugin hooks, updates generator and import utilities to honor node metadata, and introduces an MDX route-generation plugin plus test fixtures and snapshots.

Changes

Cohort / File(s) Summary
Plugin API & Types
packages/router-generator/src/plugin/types.ts, packages/router-generator/src/types.ts
Adds plugin hooks: transformNodes, isBuiltInFile, getAdditionalRouteTreeContent, afterTransform; extends onRouteTreeChanged to include config; expands RouteNode with componentImport, extension, skipTransform, and template.
Route node collection
packages/router-generator/src/filesystem/physical/getRouteNodes.ts
Accepts plugins in config, makes routeNodes mutable, computes isBuiltinFile using built-ins + plugin hook, and invokes plugin transformNodes after traversal to allow mutation/replacement of route nodes before root resolution.
Route generation & node handling
packages/router-generator/src/generator.ts
Introduces isExternal classification, separates external vs virtual imports, uses node.skipTransform/node.template, derives import/export from node.componentImport, adds node.extension to route fragments, and merges plugin getAdditionalRouteTreeContent imports into the final route tree.
Import path & specifier utilities
packages/router-generator/src/utils.ts
getImportForRouteNode uses node.componentImport?.exportName ?? 'Route'; getImportPath respects componentImport?.keepExtension and can emit absolute paths when configured.
MDX plugin & test wiring
packages/router-generator/tests/plugins/mdx.ts, packages/router-generator/tests/generator.test.ts
Adds mdxRouteGen() plugin: detects .mdx, marks MDX nodes virtual/skipTransform when TSX sibling exists, generates TSX wrapper templates for MDX siblings, produces additional route-tree imports, and wires plugin into tests via a mdx-route-gen config case.
MDX test fixtures & snapshots
packages/router-generator/tests/generator/mdx-route-gen/...
Adds MDX/TSX route fixtures and generated routeTree snapshots demonstrating plugin-driven node annotations, lazy loading, imports, and final route-tree output.
Vue test snapshots
packages/router-generator/tests/generator/vue-route-gen/...
Adds Vue route generator snapshots and root route fixture used in tests.

Sequence Diagram(s)

sequenceDiagram
    actor Dev as Developer/Test
    participant FS as Filesystem Traversal
    participant Generator
    participant Plugins
    participant RouteNodes as RouteNodes[]
    participant GeneratorPipeline as Route Generation Pipeline

    Dev->>Generator: run generator (config + plugins)
    Generator->>FS: traverse routesDirectory, collect files
    FS->>Plugins: call isBuiltInFile(file) for built-in detection
    FS-->>RouteNodes: emit initial routeNodes
    RouteNodes->>Plugins: call transformNodes({ routeNodes, config })
    Plugins-->>RouteNodes: return mutated/replaced routeNodes (if any)
    RouteNodes->>GeneratorPipeline: provide final nodes
    GeneratorPipeline->>Plugins: call getAdditionalRouteTreeContent({...})
    Plugins-->>GeneratorPipeline: return extra imports/content
    GeneratorPipeline->>Generator: assemble final routeTree and write files
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Inspect plugin type signatures and usages in plugin/types.ts.
  • Verify transformNodes ordering and mutation safety in getRouteNodes.ts.
  • Confirm isExternal / skipTransform behavior consistency in generator.ts.
  • Validate import resolution: componentImport fields, keepExtension, and absolute path handling in utils.ts.
  • Review MDX plugin sibling detection, template generation, and produced import declarations.

Possibly related PRs

Suggested reviewers

  • schiller-manuel

Poem

🐇
I hopped the folders, sniffed each file's name,
I nudged the nodes and taught plugins their game,
MDX friends found wrappers, imports now aligned,
The route-tree hums tidy, all woven and signed—
Carrots for CI, and a dance in the frame!

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 PR title 'feat: plugin-driven route generation' clearly and concisely summarizes the main change: introducing plugin-driven capabilities to the route generator, which aligns with all file modifications and the stated objective.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

const exportName =
fileNode.componentImport?.exportName ??
// For .vue files, use 'default' as the export name since Vue SFCs export default
(isVueFile ? 'default' : d[0])
Copy link
Author

Choose a reason for hiding this comment

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

Can probably have a built-in Vue plugin. Purposely didn't want to make crazy changes in this PR, but open to composing the Vue stuff in a plugin.

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

🧹 Nitpick comments (1)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (1)

258-269: Type assertion may mask missing config properties.

The config as Config assertion on line 263 asserts a Pick<Config, ...> to full Config. If a plugin's transformNodes implementation accesses properties outside the picked subset, it will receive undefined at runtime without TypeScript catching it.

Consider either:

  1. Expanding the Pick to include all properties plugins might need, or
  2. Passing a typed partial and updating the RouterGeneratorPlugin.transformNodes signature to accept Partial<Config>.
-      const result = plugin.transformNodes({
-        routeNodes,
-        config: config as Config,
-      })
+      const result = plugin.transformNodes({
+        routeNodes,
+        config,
+      })

This would require updating the transformNodes type signature in plugin/types.ts to accept the partial config type.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12817c6 and 35190fa.

📒 Files selected for processing (25)
  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts (5 hunks)
  • packages/router-generator/src/generator.ts (11 hunks)
  • packages/router-generator/src/plugin/types.ts (1 hunks)
  • packages/router-generator/src/types.ts (2 hunks)
  • packages/router-generator/src/utils.ts (3 hunks)
  • packages/router-generator/tests/generator.test.ts (2 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/(marketing)/pricing.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/_layout.tsx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/_layout/faq.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/about.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/blog.index.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/contact.lazy.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/$postId.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/index.mdx (1 hunks)
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx (1 hunks)
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts (1 hunks)
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts (1 hunks)
  • packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx (1 hunks)
  • packages/router-generator/tests/plugins/mdx.ts (1 hunks)
🧰 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/mdx-route-gen/routes/_layout.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx
  • packages/router-generator/src/types.ts
  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/plugins/mdx.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx
  • packages/router-generator/src/utils.ts
  • packages/router-generator/src/generator.ts
  • packages/router-generator/src/plugin/types.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/mdx-route-gen/routes/_layout.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx
  • packages/router-generator/src/types.ts
  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/plugins/mdx.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx
  • packages/router-generator/src/utils.ts
  • packages/router-generator/src/generator.ts
  • packages/router-generator/src/plugin/types.ts
🧠 Learnings (12)
📓 Common learnings
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
📚 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`, 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/mdx-route-gen/routes/_layout.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/about.mdx
  • packages/router-generator/src/types.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/contact.lazy.mdx
  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/$postId.mdx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/blog.index.mdx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/plugins/mdx.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.mdx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/_layout/faq.mdx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/index.mdx
  • packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx
  • packages/router-generator/src/utils.ts
  • packages/router-generator/src/plugin/types.ts
📚 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/mdx-route-gen/routes/_layout.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/about.mdx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/(marketing)/pricing.mdx
  • packages/router-generator/src/types.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/contact.lazy.mdx
  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/$postId.mdx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/blog.index.mdx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/plugins/mdx.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.mdx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/_layout/faq.mdx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/index.mdx
  • packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx
  • packages/router-generator/src/utils.ts
  • packages/router-generator/src/generator.ts
  • packages/router-generator/src/plugin/types.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/mdx-route-gen/routes/_layout.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx
  • packages/router-generator/src/types.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
  • packages/router-generator/src/generator.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/mdx-route-gen/routes/index.tsx
  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/plugins/mdx.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator.test.ts
  • packages/router-generator/src/generator.ts
  • packages/router-generator/src/plugin/types.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 **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code

Applied to files:

  • packages/router-generator/src/filesystem/physical/getRouteNodes.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 docs/**/*.{md,mdx} : Use relative links to `docs/` folder format (e.g., `./guide/data-loading`) for internal documentation references

Applied to files:

  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routes/docs.mdx
📚 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/mdx-route-gen/routes/docs.tsx
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
📚 Learning: 2025-12-16T02:59:06.535Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6104
File: packages/start-plugin-core/tests/split-exports-plugin/snapshots/exports/functionExports.ts:1-1
Timestamp: 2025-12-16T02:59:06.535Z
Learning: In transformation test snapshots (e.g., split-exports plugin), comments at the top of snapshot files often describe the original input scenario being tested (e.g., "Multiple function exports") rather than the transformed output in the snapshot itself. This helps document what transformation is being validated.

Applied to files:

  • packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.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/vue-route-gen/routeTree.snapshot.ts
  • packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts
  • packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts
  • packages/router-generator/src/utils.ts
📚 Learning: 2025-10-01T18:30:26.591Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 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-generator/src/utils.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
🧬 Code graph analysis (9)
packages/router-generator/tests/generator/mdx-route-gen/routes/_layout.tsx (5)
packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx (5)
packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/_layout.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts (2)
packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts (6)
  • FileRoutesByFullPath (93-104)
  • FileRoutesByTo (105-115)
  • FileRoutesById (116-129)
  • FileRouteTypes (130-168)
  • RootRouteChildren (169-178)
  • routeTree (297-299)
packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts (6)
  • FileRoutesByFullPath (13-13)
  • FileRoutesByTo (14-14)
  • FileRoutesById (15-17)
  • FileRouteTypes (18-25)
  • RootRouteChildren (26-26)
  • routeTree (33-35)
packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts (1)
packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts (6)
  • FileRoutesByFullPath (13-13)
  • FileRoutesByTo (14-14)
  • FileRoutesById (15-17)
  • FileRouteTypes (18-25)
  • RootRouteChildren (26-26)
  • routeTree (33-35)
packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx (4)
packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/_layout.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts (1)
e2e/solid-router/js-only-file-based/src/routeTree.gen.js (4)
  • PostsRouteRoute (25-29)
  • PostsIndexRoute (35-39)
  • PostsRouteRouteWithChildren (68-70)
  • PostsRouteRouteChildren (63-66)
packages/router-generator/tests/generator.test.ts (1)
packages/router-generator/tests/plugins/mdx.ts (1)
  • mdxRouteGen (6-112)
packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx (5)
packages/router-generator/tests/generator/mdx-route-gen/routes/_layout.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx (1)
  • Route (3-5)
packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx (1)
  • Route (3-5)
packages/router-generator/src/generator.ts (3)
packages/router-generator/src/types.ts (2)
  • RouteNode (3-24)
  • ImportDeclaration (57-61)
scripts/llms-generate.mjs (1)
  • imports (116-116)
packages/router-generator/src/utils.ts (2)
  • replaceBackslash (146-148)
  • removeExt (241-243)
🪛 Biome (2.1.2)
packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts

[error] 13-13: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


[error] 14-14: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


[error] 26-26: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts

[error] 13-13: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


[error] 14-14: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


[error] 26-26: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

🔇 Additional comments (31)
packages/router-generator/tests/generator/mdx-route-gen/routes/blog.index.mdx (1)

1-3: LGTM!

Simple and appropriate MDX test fixture for validating the MDX route generation plugin.

packages/router-generator/tests/generator/mdx-route-gen/routes/_layout/faq.mdx (1)

1-3: LGTM!

Appropriate MDX test fixture for validating MDX routes under a pathless layout.

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

13-13: LGTM!

Import is correctly placed and follows the existing import structure.


158-160: LGTM!

The new switch case follows the established pattern for folder-specific configuration. The plugin is correctly instantiated via its factory function.

packages/router-generator/tests/generator/vue-route-gen/routes/__root.tsx (1)

1-5: LGTM!

Valid root route definition using createRootRoute with an Outlet component. The structure is consistent with other root route files in the test suite.

packages/router-generator/tests/generator/mdx-route-gen/routes/index.tsx (1)

1-5: LGTM!

Standard index route definition with appropriate component. Consistent with the MDX route generation test suite structure.

packages/router-generator/tests/generator/mdx-route-gen/routes/posts/route.tsx (1)

1-5: LGTM!

Properly structured layout route with Outlet for rendering nested routes under /posts.

packages/router-generator/tests/generator/mdx-route-gen/routes/_layout.tsx (1)

1-5: LGTM!

Correct pathless layout route definition following TanStack Router conventions with the underscore prefix.

packages/router-generator/tests/plugins/mdx.ts (4)

6-12: LGTM!

Plugin factory and isBuiltInFile hook are correctly implemented with a clear MDX file detection.


14-42: LGTM!

The MDX file handling logic correctly:

  • Detects TSX siblings and marks MDX as virtual when a sibling exists
  • Sets up component imports with keepExtension: true for standalone MDX routes
  • Uses skipTransform appropriately to prevent further processing

44-78: LGTM!

The TSX sibling detection and template scaffolding logic is well-structured. When a TSX file has an MDX sibling, it correctly sets up the template to import the MDX component.


81-110: LGTM!

The getAdditionalRouteTreeContent implementation correctly:

  • Filters MDX nodes that need RouteComponent imports
  • Builds proper relative paths using path.relative and replaceBackslash
  • Returns well-formed ImportDeclaration objects
packages/router-generator/tests/generator/mdx-route-gen/routes/posts/$postId.mdx (1)

1-3: LGTM! Appropriate test fixture for dynamic MDX routes.

This MDX file correctly tests dynamic route parameter handling with the $postId parameter pattern. The minimal content is intentional for testing route generation behavior.

packages/router-generator/tests/generator/mdx-route-gen/routes/posts/index.mdx (1)

1-3: LGTM! Appropriate test fixture for index MDX routes.

This MDX file correctly tests index route generation for the /posts path. The minimal content is intentional for testing purposes.

packages/router-generator/tests/generator/mdx-route-gen/routes/docs.mdx (1)

1-3: LGTM! Correctly tests MDX/TSX sibling handling.

This test fixture verifies that the MDX route generator plugin properly handles the scenario where an MDX file has a corresponding TSX sibling (docs.tsx). The self-documenting comment clarifies the expected behavior: the MDX should be skipped in favor of the TSX route.

packages/router-generator/tests/generator/mdx-route-gen/routes/(marketing)/pricing.mdx (1)

1-3: LGTM! Appropriate test fixture for MDX routes in route groups.

This MDX file correctly tests route group handling (pathless routes) with MDX content. The file structure (marketing)/pricing.mdx validates that the generator properly handles MDX files within route groups.

packages/router-generator/tests/generator/mdx-route-gen/routes/contact.lazy.mdx (1)

1-3: LGTM! Appropriate test fixture for lazy-loaded MDX routes.

This MDX file correctly tests lazy route loading with the .lazy suffix convention. The minimal content is intentional for validating the generator's lazy-loading behavior with MDX files.

packages/router-generator/tests/generator/mdx-route-gen/routes/about.mdx (1)

1-3: LGTM! Appropriate test fixture for standalone MDX routes.

This MDX file serves as a baseline test case for basic MDX route generation without special features (no dynamic params, no lazy loading, no route groups). The minimal content is intentional.

packages/router-generator/tests/generator/mdx-route-gen/routes/__root.tsx (1)

1-5: LGTM! Standard root route pattern.

This root route definition follows the established TanStack Router pattern and matches the structure used in other test suites (e.g., vue-route-gen/__root.tsx). The typed API provides type safety without explicit type annotations.

packages/router-generator/tests/generator/mdx-route-gen/routes/docs.tsx (1)

1-5: LGTM! Correct TSX sibling for MDX/TSX coexistence testing.

This TSX file serves as the sibling to docs.mdx and tests the plugin's behavior when both MDX and TSX files exist for the same route. Following the expected behavior, this TSX route should take precedence over the MDX file. The file route pattern follows standard TanStack Router conventions.

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

1-2: LGTM! Well-structured type extensions for plugin support.

The new optional properties (componentImport, extension, skipTransform, template) are appropriately typed and extend RouteNode in a backwards-compatible manner. The TargetTemplate['route'] indexed access type correctly references the template configuration.

Also applies to: 19-22

packages/router-generator/src/filesystem/physical/getRouteNodes.ts (1)

135-143: LGTM! Plugin-aware built-in file detection.

The logic correctly uses short-circuit evaluation to check standard extensions first, then delegates to plugins via isBuiltInFile. This allows plugins to register custom file types (e.g., .mdx) as route files.

packages/router-generator/tests/generator/vue-route-gen/routeTree.nonnested.snapshot.ts (1)

1-35: Auto-generated snapshot file - no changes required.

This is a test fixture that verifies the generator's output. The empty interfaces and structure are intentional for type augmentation patterns in TanStack Router. Based on learnings, test snapshot files should not be modified.

packages/router-generator/tests/generator/vue-route-gen/routeTree.snapshot.ts (1)

1-35: Auto-generated snapshot file - no changes required.

This test fixture verifies Vue route generation output. The structure matches the expected pattern for TanStack Router generated files. Based on learnings, test snapshot files should not be modified.

packages/router-generator/tests/generator/mdx-route-gen/routeTree.nonnested.snapshot.ts (1)

1-299: Auto-generated MDX route snapshot - comprehensive test fixture.

This snapshot correctly demonstrates the MDX route generation plugin output, including:

  • MDX component imports with proper default export handling
  • Lazy loading pattern for the contact route
  • Complete parent-child route relationships
  • Proper module augmentation for @tanstack/react-router

Based on learnings, test snapshot files should not be modified as they verify generator output.

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

9-68: Well-designed plugin API with clear contracts.

The GeneratorPlugin interface is well-structured with:

  • Consistent parameter object patterns across all hooks
  • Appropriate optional return types (| void) for transform hooks
  • Required name property for plugin identification
  • Clear JSDoc documentation for each hook's purpose
packages/router-generator/src/utils.ts (1)

751-799: LGTM!

The import path and specifier logic correctly handles:

  • Dynamic keepExtension flag from node.componentImport with sensible default (false)
  • Dynamic exportName from node.componentImport with fallback to 'Route'
  • Consistent handling for both relative and absolute import paths

The implementation aligns well with the new RouteNode.componentImport type definition.

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

553-582: LGTM on the external node filtering logic.

The isExternal helper cleanly encapsulates the condition for nodes that require actual file imports (not virtual and not skip-transform). This is used consistently for:

  • routeImports filtering
  • virtualRouteNodes filtering
  • createFileRoute import requirement check

924-936: LGTM on plugin content collection.

The loop correctly collects additional imports from all plugins via getAdditionalRouteTreeContent and merges them into the final import set before mergeImportDeclarations is called.


1050-1108: LGTM on skipTransform integration.

The skipTransform flag is correctly checked before:

  1. Scaffolding new route files (line 1050)
  2. Transforming existing files (line 1108)

This allows plugins to mark nodes that should bypass the standard transformation pipeline (e.g., MDX files that don't need Route export injection).

packages/router-generator/tests/generator/mdx-route-gen/routeTree.snapshot.ts (1)

1-299: Snapshot file - skipping review.

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

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

🧹 Nitpick comments (1)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (1)

135-143: Prefer some() over find() for boolean intent.

The isBuiltinFile variable is used as a boolean condition, but find() returns the plugin object (or undefined). Using some() would be more semantically accurate and make the intent clearer.

 const isBuiltinFile =
   fullPath.match(/\.(tsx|ts|jsx|js|vue)$/) ||
-  plugins.find((p) =>
+  plugins.some((p) =>
     p.isBuiltInFile?.({
       fileName: dirent.name,
       fullPath,
       relativePath,
     }),
   )
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35190fa and 39328d6.

📒 Files selected for processing (2)
  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts (5 hunks)
  • packages/router-generator/src/plugin/types.ts (1 hunks)
🧰 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/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/src/plugin/types.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/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/src/plugin/types.ts
🧠 Learnings (6)
📓 Common learnings
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
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.
📚 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/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/src/plugin/types.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`, 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/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/src/plugin/types.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/src/filesystem/physical/getRouteNodes.ts
  • packages/router-generator/src/plugin/types.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/src/filesystem/physical/getRouteNodes.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 **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code

Applied to files:

  • packages/router-generator/src/filesystem/physical/getRouteNodes.ts
🧬 Code graph analysis (1)
packages/router-generator/src/filesystem/physical/getRouteNodes.ts (3)
packages/router-plugin/src/core/router-generator-plugin.ts (1)
  • config (143-145)
packages/router-generator/src/types.ts (1)
  • RouteNode (3-24)
packages/router-generator/src/config.ts (1)
  • Config (66-66)
🔇 Additional comments (2)
packages/router-generator/src/plugin/types.ts (1)

1-67: Well-structured plugin interface with clear lifecycle hooks.

The interface design is clean with proper JSDoc documentation for each hook. The optional return types (e.g., Array<RouteNode> | void for transformNodes) follow a sensible pattern for allowing plugins to optionally mutate data.

packages/router-generator/src/filesystem/physical/getRouteNodes.ts (1)

42-52: Good defensive initialization for plugins.

Defaulting plugins = [] prevents potential runtime errors when calling plugins.find() or iterating. Changing routeNodes to let correctly allows reassignment after plugin transformations.

Comment on lines +258 to +269
// Let plugins transform nodes.
for (const plugin of plugins) {
if (plugin.transformNodes) {
const result = plugin.transformNodes({
routeNodes,
config: config as Config,
})
if (result) {
routeNodes = result
}
}
}
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the getRouteNodes.ts file to see the exact Pick and config usage
echo "=== getRouteNodes.ts config usage (lines 250-270) ==="
rg -n "config as Config" packages/router-generator/src/filesystem/physical/getRouteNodes.ts -B 15 -A 5

echo ""
echo "=== getRouteNodes.ts Pick usage ==="
rg -n "Pick<Config" packages/router-generator/src/filesystem/physical/getRouteNodes.ts -A 10

Repository: TanStack/router

Length of output: 1279


🏁 Script executed:

#!/bin/bash
# Check the function signature of getRouteNodes to see what config parameter type is
echo "=== getRouteNodes function signature ==="
rg -n "export.*async.*getRouteNodes|function getRouteNodes" packages/router-generator/src/filesystem/physical/getRouteNodes.ts -A 8

echo ""
echo "=== transformNodes plugin type definition ==="
rg -n "transformNodes" packages/router-generator/src -l

echo ""
echo "=== Plugin interface definition ==="
rg -n "interface.*Plugin|type.*Plugin" packages/router-generator/src -A 10 | head -80

echo ""
echo "=== Full Config type ==="
rg -n "^export.*type Config|^export.*interface Config" packages/router-generator/src/config.ts -A 20

Repository: TanStack/router

Length of output: 4563


🏁 Script executed:

#!/bin/bash
# Get the full configSchema to see all properties
echo "=== Full configSchema ==="
rg -n "const configSchema" packages/router-generator/src/config.ts -A 50

echo ""
echo "=== transformNodes method signature ==="
rg -n "transformNodes" packages/router-generator/src/plugin/types.ts -A 10

Repository: TanStack/router

Length of output: 2220


🏁 Script executed:

#!/bin/bash
# Check what the full Pick includes in getRouteNodes
echo "=== Full Pick in getRouteNodes (lines 28-40) ==="
sed -n '28,40p' packages/router-generator/src/filesystem/physical/getRouteNodes.ts

echo ""
echo "=== Search for any example/test plugins that might use transformNodes ==="
find packages/router-generator -name "*.ts" -type f | xargs grep -l "transformNodes" | head -5

echo ""
echo "=== Check if any plugins access Config properties beyond the Pick ==="
rg -n "config\." packages/router-generator/src --type ts | grep -i "transform\|plugin" | head -20

Repository: TanStack/router

Length of output: 770


🏁 Script executed:

#!/bin/bash
# Check the mdx plugin to see what properties it accesses from config
echo "=== mdx.ts plugin - what config properties are used ==="
cat packages/router-generator/tests/plugins/mdx.ts

echo ""
echo "=== Search for any other references to transformNodes in the codebase ==="
rg -n "transformNodes" packages/router-generator -A 5 -B 2 --type ts

Repository: TanStack/router

Length of output: 5506


🏁 Script executed:

#!/bin/bash
# Check if verboseFileRoutes and generatedRouteTree are in the Pick
echo "=== Checking if verboseFileRoutes is in the Pick ==="
grep -n "verboseFileRoutes\|generatedRouteTree" packages/router-generator/src/filesystem/physical/getRouteNodes.ts | head -10

echo ""
echo "=== Check baseConfigSchema to see all base properties ==="
sed -n '7,33p' packages/router-generator/src/config.ts

echo ""
echo "=== Verify the mdx plugin is actually being tested/used ==="
find packages/router-generator/tests -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "mdx" 2>/dev/null | head -3

Repository: TanStack/router

Length of output: 1340


🏁 Script executed:

#!/bin/bash
# Final verification - check what config.verboseFileRoutes and config.generatedRouteTree are in baseConfigSchema
echo "=== Properties that mdx plugin uses but are not in the Pick ==="
echo "1. config.verboseFileRoutes - is it in baseConfigSchema? (should see result below)"
grep -n "verboseFileRoutes" packages/router-generator/src/config.ts

echo ""
echo "2. config.generatedRouteTree - is it in baseConfigSchema? (should see result below)"
grep -n "generatedRouteTree" packages/router-generator/src/config.ts

echo ""
echo "=== Location of these in schema ==="
rg -n "verboseFileRoutes|generatedRouteTree" packages/router-generator/src/config.ts -B 2

Repository: TanStack/router

Length of output: 1516


Type cast config as Config may cause runtime issues for plugins.

The function receives Pick<Config, 'plugins' | 'routesDirectory' | 'routeFilePrefix' | 'routeFileIgnorePrefix' | 'routeFileIgnorePattern' | 'disableLogging' | 'routeToken' | 'indexToken' | 'experimental'> but casts it to the full Config type, hiding a mismatch. The mdx plugin (and potentially others) accesses properties like config.verboseFileRoutes and config.generatedRouteTree that aren't included in the Pick, which will be undefined at runtime.

Consider either:

  1. Expanding the Pick to include all properties plugins might need, or
  2. Updating the transformNodes type signature to accept the same Pick type

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)

691-720: Consider extracting duplicated component import logic.

The logic for determining exportName, keepExtension, and importPath from fileNode.componentImport is duplicated in three places:

  • Lines 691-720 (component pieces)
  • Lines 731-760 (lazy component pieces)
  • Lines 801-831 (root route component pieces)

While the implementation is consistent across all locations, extracting this into a helper function would improve maintainability and reduce the risk of divergence in future changes.

Example helper:

function getComponentImportInfo(fileNode: RouteNode, defaultExportName: string, config: Config) {
  const isVueFile = fileNode.filePath.endsWith('.vue')
  const exportName = fileNode.componentImport?.exportName ?? (isVueFile ? 'default' : defaultExportName)
  const keepExtension = fileNode.componentImport?.keepExtension ?? isVueFile
  const importPath = replaceBackslash(
    keepExtension
      ? path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, fileNode.filePath))
      : removeExt(path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, fileNode.filePath)), config.addExtensions)
  )
  return { exportName, importPath }
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 39328d6 and da28d98.

📒 Files selected for processing (1)
  • packages/router-generator/src/generator.ts (11 hunks)
🧰 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/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/src/generator.ts
🧠 Learnings (5)
📓 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.
📚 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/src/generator.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/src/generator.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/src/generator.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
🧬 Code graph analysis (1)
packages/router-generator/src/generator.ts (6)
packages/router-generator/src/types.ts (2)
  • RouteNode (3-24)
  • ImportDeclaration (57-61)
scripts/llms-generate.mjs (1)
  • imports (116-116)
packages/router-plugin/src/core/code-splitter/compilers.ts (1)
  • ImportDeclaration (908-916)
packages/router-generator/src/utils.ts (2)
  • replaceBackslash (146-148)
  • removeExt (241-243)
packages/router-core/src/route.ts (1)
  • path (1553-1555)
packages/router-plugin/src/core/router-generator-plugin.ts (1)
  • config (143-145)
🔇 Additional comments (6)
packages/router-generator/src/generator.ts (6)

519-527: LGTM: Plugin API extended with config parameter.

The addition of config: this.config to the onRouteTreeChanged callback enables plugins to access the generator configuration, which aligns with the plugin-driven route generation objectives.


553-577: LGTM: Clear separation of external vs. non-external route nodes.

The isExternal helper creates a consistent classification that distinguishes route nodes backed by physical imports from virtual or transform-skipped nodes. The logic is applied consistently across route imports, virtual route definitions, and the createFileRoute import condition.


731-760: LGTM: Export accessor correctly uses dynamic export name.

Line 739 correctly constructs the export accessor using the actual exportName value via template literal interpolation. This properly handles both default exports and custom export names (e.g., 'MyCustomRoute''d.MyCustomRoute').


763-763: LGTM: Extension metadata support for plugin-driven generation.

Appending node.extension allows plugins to inject custom metadata or method calls into the route definition, supporting the plugin-driven route generation feature.


923-935: LGTM: Plugin-contributed imports enhance extensibility.

The getAdditionalRouteTreeContent hook enables plugins to inject custom imports into the generated route tree. Providing comprehensive context (routeTree, routeNodes, rootRouteNode, acc, config) gives plugins sufficient information to make informed decisions about what content to contribute.


1049-1107: LGTM: Consistent skipTransform handling and template override support.

The skipTransform checks (lines 1049, 1107) consistently prevent both scaffolding and transformation when a node opts out, which is correct for plugin-generated routes that don't require file manipulation. The per-node template override (line 1085) provides flexibility for plugins to specify custom scaffolding templates.

import type { Generator } from '../generator'
import type { Config } from '../config'

export interface GeneratorPlugin {
Copy link
Contributor

Choose a reason for hiding this comment

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

the GeneratorPlugin in its entirety cannot become public API as we can't maintain this.

what's the absolute minimum API that you need to e.g. implement mdx?
we also can't expose those internal complex types such as RouteNode and HandleNodeAccumulator.

let's start with the ideal API from a plugin-author perspective and then work backwards

Copy link
Author

Choose a reason for hiding this comment

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

What is your thoughts on an ideal API? This PR caters specifically to an MDX use case, and I intentionally chose to try keep the API as minimal as possible for such.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't have an opinion about a plugin api yet. so what do you need just for the mdx case?

@schiller-manuel
Copy link
Contributor

also, this approach must work with virtual file routes as well

@nx-cloud
Copy link

nx-cloud bot commented Dec 18, 2025

View your CI Pipeline Execution ↗ for commit d5ea6a9

Command Status Duration Result
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 37s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-18 17:24:44 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 18, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: d5ea6a9

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