Skip to content

routeTree generation breaks when using different root in vite config #3624

@ensconced

Description

@ensconced

Which project does this relate to?

Router

Describe the bug

In my vite config, I have root set to "./src". Initially this resulted in an error from the TanStackRouterVite plugin due to it trying to read the routes from ./src/src/routes, but I resolved this by adding routesDirectory: "./src/routes" and generatedRouteTree: "./src/routeTree.gen.ts" to the plugin config.

With this resulting setup, everything seems to work, except that when I create new route files they don't get filled with the usual boilerplate code. And for the routeTree.gen.ts to be updated I have to kill and restart the vite dev server.

Your Example Website or App

https://stackblitz.com/edit/tanstack-router-mzkds9em?file=vite.config.js,src%2Findex.html&preset=node

Steps to Reproduce the Bug or Issue

  1. Go to the linked stackblitz
  2. See that the app works fine
  3. Try creating a new route file - it doesn't get automatically filled with the route boilerplate code
  4. Manually add the code for the new route file - see that you get a TS error from createFileRoute (because the routeTree.gen.ts hasn't been properly updated) until you kill and restart the vite dev server

Expected behavior

  • automatic filling of route files with boilerplate code should work regardless of root setting in vite config
  • routeTree.gen.ts should get properly updated when adding/updating route files regardless of root setting in vite config

Screenshots or Videos

No response

Platform

  • OS: macOS

Additional context

No response

Activity

eliellis

eliellis commented on Mar 7, 2025

@eliellis

I'm having the same issue, for now I've worked around it (somewhat) with the following Vite config (using vite-plugin-restart):

import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
import ViteRestart from "vite-plugin-restart";
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";

export default defineConfig({
  root: "src/frontend",
  build: {
    outDir: "../../dist",
  },
  plugins: [
    // remove once https://github.com/TanStack/router/issues/3624 is fixed
    ViteRestart({
      restart: ["routes/**/*.ts(x)?"],
    }),
    tsconfigPaths(),
    TanStackRouterVite({
      target: "react",
      autoCodeSplitting: true,
      routesDirectory: "src/frontend/routes",
      generatedRouteTree: "src/frontend/routeTree.gen.ts",
    }),
    tailwindcss(),
    react(),
  ],
});

This restarts the vite process completely when any .ts(x)? file changes in the routes directory, which is definitely not ideal, but gets the job done until this gets sorted.

MichaelCannucci

MichaelCannucci commented on Apr 8, 2025

@MichaelCannucci

Found a workaround, since there seems to be bug related to the Vite root config option.
Making sure the routesDirectory option is an absolute path should fix it.

Here's an example of my vite.config.ts

import path from "path"
import tailwindcss from '@tailwindcss/vite'
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    TanStackRouterVite({
      routesDirectory: path.resolve(process.cwd(), 'app/client/routes'),
      generatedRouteTree: 'app/client/routeTree.gen.ts',
    }),
    react(),
    tailwindcss()
  ],
  root: 'app/client',
  envDir: "../../",
  publicDir: 'public',
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./app"),
    },
  },
  server: {
    host: '127.0.0.1',
  }
})
renchap

renchap commented on Apr 28, 2025

@renchap

I am also facing this. Some additional debugging:

Vite root is set as app/client

With the plugin configured as:

{
      routesDirectory: "app/client/routes",
      generatedRouteTree: "app/client/routeTree.gen.ts",
}

In https://github.com/TanStack/router/blob/main/packages/router-plugin/src/core/router-generator-plugin.ts#L66 I can observe:

  • `filePath = "/app/client/routes/books/$bookId/preview.tsx"
  • routesDirectoryPath = "<prefix>/app/client/app/client/routes"
    You can notice that routesDirectoryPath adds routesDirectory after the Vite root path. Also the route tree is generated at the expected location (<prefix>/app/client/routeTree.gen.ts) without prepending the Vite root path.

Initial generation works when Vite starts, but then when files are updated the generator is not ran.

If I change the plugin settings to:

{
      routesDirectory: "routes",
      generatedRouteTree: "app/client/routeTree.gen.ts",
}

Then Vite crashes at startup with

Error: ENOENT: no such file or directory, scandir '/<prefix>/routes'
    at async Module.readdir (node:internal/fs/promises:949:18)
    at async recurse (file:///<prefix>/node_modules/@tanstack/router-generator/dist/esm/filesystem/physical/getRouteNodes.js:15:19)
    at async getRouteNodes (file:///<prefix>/node_modules/@tanstack/router-generator/dist/esm/filesystem/physical/getRouteNodes.js:127:3)
    at async generator (file:///<prefix>/node_modules/@tanstack/router-generator/dist/esm/generator.js:46:27)
    at async generate (file:///<prefix>/node_modules/@tanstack/router-plugin/dist/esm/core/router-generator-plugin.js:22:7)
    at async run (file:///<prefix>/node_modules/@tanstack/router-plugin/dist/esm/core/router-generator-plugin.js:47:7)
    at async configResolved (file:///<prefix>/node_modules/@tanstack/router-plugin/dist/esm/core/router-generator-plugin.js:61:9)
    …

So the issue seems to stem from the routes path not being computed the same way between the router start and a file update. In the first case the Vite root path is not appended, but it is in the 2nd case. It also seems to never be prepended to generatedRouteTree.

A fix would probably involve unifying the behaviour here, and I would recommend always appending Vite's root path to the routes directory path and the generated route tree path for consistency.

RMHonor

RMHonor commented on May 23, 2025

@RMHonor
Contributor

The docs state that the routesDirectory is relative to the CWD, while it seems to be relative to root on start-up.

Based on this, expected behaviour with root of ./src and routesDirectory of ./src/routes would be that it looks for routes in {cwd}/src/routes, not ./src/src/routes as witnessed.

The issue seems to be that the plugin uses the Vite root, rather than the process.cwd(), here.

This can be removed, and it'll give the documented behaviour.

RMHonor

RMHonor commented on Jun 12, 2025

@RMHonor
Contributor

Looks to be fixed in v1.121 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @renchap@eliellis@schiller-manuel@RMHonor@ensconced

      Issue actions

        routeTree generation breaks when using different root in vite config · Issue #3624 · TanStack/router