TanStack / TanStack/router

Start: user router.plugins never reach the route generator (start-plugin-core overwrites them)

Open Beginner friendly
#7,768 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

information needed
Dominant language
TypeScript
Stars
15.1k
Forks
1.9k
Avg merge
1d 20h
Merged PRs (30d)
143

Description

Which project does this relate to?

Start

Describe the bug

Generator plugins passed as tanstackStart({ router: { plugins: [...] } }) never reach the route generator — no hook (init, onRouteTreeChanged, afterTransform) is ever invoked, in dev or build, with no error or warning.

Cause: tanStackStartRouter builds its internal generator-plugin list and places it after ...routerConfig in the config it hands to tanstackRouterGenerator, so the user's plugins key is overwritten:

https://github.com/TanStack/router/blob/4eed408f12e0dee55708b1e2b53fefb3441c414d/packages/start-plugin-core/src/vite/start-router-plugin/plugin.ts#L147-L159

tanstackRouterGenerator(() => {
  const routerConfig = getConfig().startConfig.router
  const plugins = [clientTreeGeneratorPlugin, routesManifestPlugin()]
  if (startPluginOpts.prerender?.enabled === true) {
    plugins.push(prerenderRoutesPlugin())
  }
  return {
    ...routerConfig,          // includes the user's routerConfig.plugins…
    target: corePluginOpts.framework,
    routeTreeFileFooter: getRouteTreeFileFooter,
    plugins,                  // …which is clobbered here
  }
}, routerPluginContext)

The same options work correctly with the plain tanstackRouter Vite plugin (no Start), where user config flows through getConfig untouched — so this is Start-specific.

Suggested fix (verified locally via a patched package):

if (routerConfig.plugins) plugins.push(...routerConfig.plugins)
Your Example Website or App
// vite.config.ts — minimal repro
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'

export default defineConfig({
  plugins: [
    tanstackStart({
      router: {
        plugins: [
          {
            name: 'probe',
            init: () => console.error('[probe] init'),
            onRouteTreeChanged: () => console.error('[probe] onRouteTreeChanged'),
          },
        ],
      },
    }),
  ],
})
Steps to Reproduce the Bug or Issue
  1. Add the probe generator plugin above to any TanStack Start app's vite.config.ts
  2. Run vite dev or vite build
  3. Neither [probe] line is printed; with the plain tanstackRouter() plugin (non-Start), both print
Expected behavior

User-supplied router.plugins are merged with Start's internal generator plugins and their hooks fire on generator runs — or, if generator plugins are intentionally unsupported under Start, a loud error instead of silent acceptance.

Platform
  • @tanstack/react-start: 1.168.27 (start-plugin-core 1.171.19; bug still present on main)
  • OS: macOS
Additional context

Footnote once plugins do run: createRouterGeneratorPlugin wraps generator.run() in catch (e) { console.error(e) }, so a generator plugin that throws (e.g. to enforce a project invariant) can log but never fail the build. May be intentional, but it compounds the silence here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/start-plugin-core/src/vite/start-router-plugin/plugin.ts around lines 147-159, then run the minimal Vite configuration from the issue with both vite dev and vite build. Verify that user-supplied router.plugins are preserved alongside Start's internal plugins and that the probe hooks run, or that unsupported plugins produce a loud error.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vite
Domain
build-system, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.