Capítulo 19 de 57
Virtual file routes let you build a route tree programmatically in code while still pointing at real route files on disk, giving full control over route organization/URL structure without following (or while partially following) TanStack Router's file-based conventions.
@tanstack/virtual-file-routes package: Provides rootRoute, route, index, layout, and physical functions to declare a virtual route tree that maps to real files.rootRoute(file, children): Declares the virtual root route and its children array.route(path, file, children?): Declares a virtual route at path backed by file; can omit file to just apply a path prefix to nested children; leading/trailing underscores in path are treated literally (use layout for pathless behavior).index(file): Declares a virtual index route backed by file.layout(file, children) / layout(id, file, children): Declares a virtual pathless layout route; an optional explicit id disambiguates it from its filename.physical(urlPath, dir): "Mounts" a real directory that follows standard file-based routing convention under a given URL path; physical('', dir) or physical(dir) merges a directory's routes at the current level with no path prefix.__virtual.ts + defineVirtualSubtreeConfig: Lets you switch a specific subtree of an otherwise file-based-routing project into virtual configuration, via a default export (object, function, or async function returning the subtree config). No rootRoute is needed inside a subtree config.virtualRouteConfig option of the tanstackRouter bundler plugin (Vite/Rspack/Webpack), or the virtualRouteConfig key in tsr.config.json for the CLI (as a file path or inline JSON).// routes.ts
import {
rootRoute,
route,
index,
layout,
physical,
} from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
index('index.tsx'),
layout('pathlessLayout.tsx', [
route('/dashboard', 'app/dashboard.tsx', [
index('app/dashboard-index.tsx'),
route('/invoices', 'app/dashboard-invoices.tsx', [
index('app/invoices-index.tsx'),
route('$id', 'app/invoice-detail.tsx'),
]),
]),
physical('/posts', 'posts'),
]),
])
physical() mount that hands off /posts to standard file-based routing convention.physical() to fall back to normal convention for subtrees you don't need to customize.__virtual.ts allows mixing: most of the app can stay file-based while specific subtrees opt into virtual configuration, and you can nest back and forth arbitrarily deep.route(path, [children]) without a file argument is a convenient way to apply a shared path prefix to a group of children without introducing an extra component layer.physical().