File Route API Reference
Purpose and Scope
This page is a focused reference for the route-construction APIs that create TanStack Router route instances before they are handed to a router. These functions sit at the boundary between application route definitions and the route tree that TanStack Router uses for matching, loading, rendering, and type inference. Use this page when you need to decide between file-based and code-based route factories, when you are introducing a typed root context, or when you are splitting route components into lazy modules without moving critical matching and loading configuration into the lazy bundle.
The APIs covered here are all listed under the Router API function family in the official docs, but they solve different authoring problems. The file-route functions are designed for the file-based workflow where the generator or watcher can maintain route paths for you. The code-route functions are designed for explicit route tree construction where every route names its parent and path in code. The root-route helpers create the top of the route tree, and the lazy helpers attach non-critical render properties to routes that are loaded only after a route has matched.
Sources: docs/router/api/router/createFileRouteFunction.md, docs/router/api/router/createLazyFileRouteFunction.md, docs/router/api/router/createRouteFunction.md, docs/router/api/router/createRootRouteFunction.md, docs/router/api/router/createRootRouteWithContextFunction.md, docs/router/api/router/createLazyRouteFunction.md
Relevant Source Files
- docs/router/api/router/createFileRouteFunction.md — Defines the file-based factory, its path argument, the generated-route-tree workflow, the Route export requirement, and a loader/component example.
- docs/router/api/router/createLazyFileRouteFunction.md — Defines the lazy file-based factory and limits its options to non-critical route properties such as components and error display components.
- docs/router/api/router/createRouteFunction.md — Defines the code-based route factory, the required RouteOptions input, and the relationship between child routes and a root route.
- docs/router/api/router/createRootRouteFunction.md — Defines root route creation, the root-only option shape, and the routeTree creation flow before calling createRouter.
- docs/router/api/router/createRootRouteWithContextFunction.md — Defines the typed root-context helper and shows how router creation must fulfill the declared context type.
- docs/router/api/router/createLazyRouteFunction.md — Defines code-based lazy route modules, the route id argument, the limited option pick, and the required manual lazy attachment step.
Choosing the Right Factory
Choose the file-based factory when each route module corresponds to a route file and you want the tooling to generate a route tree. In that workflow, the route file exports a route instance named Route, and the generator or watcher inserts and updates the file path argument. This is intentionally different from hand-maintained route paths: the source docs describe the path argument as required, but also as automatically inserted and updated by the route-generation commands. That means application authors should treat the first argument as part of the file-routing contract rather than as ordinary business logic.
Choose the code-based factory when your route hierarchy is declared directly in TypeScript or TSX. A code route receives RouteOptions, including a getParentRoute callback and a path, and the resulting route instance is passed into a parent root route's children to form the route tree. This is the lower-level model that file-based routing ultimately serves: the router still receives a tree, but the tree may be generated from files or assembled directly in code. The docs example makes this explicit by creating an index route whose parent is the root route and whose component reads loader data through the route instance.
Lazy factories should not be treated as replacements for the full route factories. Both lazy APIs create partial route instances that can configure only non-critical route properties. In the supplied docs, the allowed properties are component, pending component, error component, and not-found component. Critical route configuration, such as matching information and data-loading dependencies, must remain available before the lazy module is loaded. This distinction is important because the router must know how to match and prepare a route before it can safely fetch the module that renders the matched route.
Sources: docs/router/api/router/createFileRouteFunction.md, docs/router/api/router/createLazyFileRouteFunction.md, docs/router/api/router/createRouteFunction.md, docs/router/api/router/createLazyRouteFunction.md
Compact API Reference
| API | Primary workflow | First argument | Configuration argument | Return value and key behavior |
|---|---|---|---|---|
| createFileRoute | File-based routing | string literal path for the source file | RouteOptions | Returns a function that creates a file Route instance used by generation and watch commands. |
| createLazyFileRoute | File-based code splitting | string path for the source file | Pick of non-critical RouteOptions | Returns a function that creates a lazy partial file Route instance. |
| createRoute | Code-based routing | none; options are the argument | RouteOptions | Returns a Route instance that can be added to a root route's children. |
| createRootRoute | Code-based or generated route tree root | none; options are the argument | Root-compatible RouteOptions omit path, id, parent, case sensitivity, and param parse/stringify fields | Returns a root Route instance. |
| createRootRouteWithContext | Root route with required router context | generic context type | same options as createRootRoute after invoking the helper | Returns a factory that creates a typed root Route instance. |
| createLazyRoute | Code-based code splitting | string route id | Pick of non-critical RouteOptions | Returns a function that creates a lazy partial route that must be attached with lazy. |
The most common file-route shape is a two-step call. First, the file path identifies the route file. Second, the returned function receives route options such as a loader and component. The docs state that the route instance must be exported from the file using the Route identifier for generation and watch commands to work properly. That export name is not a cosmetic convention; it is the connection point the tooling uses when it scans files and updates generated route-tree output.
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
loader: () => 'Hello World',
component: IndexComponent,
})
function IndexComponent() {
const data = Route.useLoaderData()
return <div>{data}</div>
}The equivalent code-based route starts from an existing root route and names its parent explicitly. The route options include getParentRoute, path, loader, and component in the documented example. This style is useful when routes are easier to express as a central tree or when you want route construction to be independent of a file naming convention. It also makes the parent-child relationship visible at the point where the route is declared, which can be helpful in libraries, examples, and small applications that do not need generator-driven routing.
import { createRoute } from '@tanstack/react-router'
import { rootRoute } from './__root'
const Route = createRoute({
getParentRoute: () => rootRoute,
path: '/',
loader: () => 'Hello World',
component: IndexComponent,
})Sources: docs/router/api/router/createFileRouteFunction.md, docs/router/api/router/createRouteFunction.md
Root Route and Typed Context
Every route tree needs a root. The basic root helper returns a new root route instance, and that instance can call addChildren to create a route tree that is then passed to createRouter. The root route option type intentionally omits fields that make sense only for ordinary child routes, including path, id, getParentRoute, case sensitivity, and param parse or stringify hooks. In practice, this means the root route is where shared shell UI and root-level route behavior belongs, not where you declare a URL segment.
Use the context-aware root helper when the router must be created with application services that routes can depend on. The docs show an interface containing a QueryClient, then call the helper with that type parameter before passing a context object into createRouter. This pattern makes dependency injection explicit: the root route declares the required context shape, and router construction must fulfill it. It is especially useful for data-layer objects, authentication state, environment adapters, or other shared dependencies that loaders and route code should access through router context rather than imports.
import { createRootRouteWithContext, createRouter, Outlet } from '@tanstack/react-router'
import { QueryClient } from '@tanstack/react-query'
interface MyRouterContext {
queryClient: QueryClient
}
const rootRoute = createRootRouteWithContext<MyRouterContext>()({
component: () => <Outlet />,
})
const routeTree = rootRoute.addChildren([])
const queryClient = new QueryClient()
const router = createRouter({
routeTree,
context: { queryClient },
})Sources: docs/router/api/router/createRootRouteFunction.md, docs/router/api/router/createRootRouteWithContextFunction.md
Lazy Route APIs and Critical Configuration
The lazy file-route helper is the file-based counterpart to route-level code splitting. It accepts the same kind of generated path argument as createFileRoute, but its returned function accepts only the non-critical subset of route options. The docs list component, pendingComponent, errorComponent, and notFoundComponent as the allowed properties. This keeps the initial route tree able to match URLs and prepare navigation while postponing UI implementation details until the route is matched and the lazy module is loaded.
The code-based lazy helper follows the same non-critical-property rule, but it is identified by route id rather than by a generated file path. The docs also call out an extra manual step: the lazy route instance must be loaded against its critical route instance using the lazy method returned by createRoute. A typical code-based setup therefore defines a critical route with parent and path, then calls lazy with a dynamic import that resolves to the lazy Route export. This preserves early route matching while moving the component module out of the initial bundle.
// src/route-pages/index.tsx
import { createLazyRoute } from '@tanstack/react-router'
export const Route = createLazyRoute('/')({
component: IndexComponent,
})
// src/routeTree.tsx
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
}).lazy(() => import('./route-pages/index').then((d) => d.Route))When debugging lazy routes, verify that critical and non-critical responsibilities are separated correctly. If matching, parentage, or route identity lives only in a lazy module, the router cannot rely on that information before loading the module. If the lazy file route is not exported as Route, the generation and watch workflow will not have the documented export shape it expects. If a code-based lazy route is created but never attached with lazy, the critical route remains present, but the lazy component configuration is not connected to it.
Sources: docs/router/api/router/createLazyFileRouteFunction.md, docs/router/api/router/createLazyRouteFunction.md
Task Flow and Next Steps
For a new file-based route, create the route file, export const Route, call the file-route factory with the generated path argument, and place route options in the returned function call. Then run the generation or watch workflow so the route tree reflects the file system. For a new code-based route, create or import the root route, create the child route with getParentRoute and path, add it with addChildren, and pass the resulting route tree to createRouter. Both workflows produce route instances, but the maintenance responsibility is different: file routing delegates path bookkeeping to tooling, while code routing makes the tree explicit.
For a new application shell, start with createRootRoute unless routes need typed access to shared router context. If they do, declare the context interface with createRootRouteWithContext and provide a matching context object when the router is created. For code splitting, keep loaders, identity, and matching-critical fields in the non-lazy route, then move only supported UI properties into createLazyFileRoute or createLazyRoute modules. After this page, read the route options and route type reference to understand the full configuration surface, then read the code-splitting and file-based-routing pages for the build-time behavior around generated route trees.
Sources: docs/router/api/router/createFileRouteFunction.md, docs/router/api/router/createRootRouteWithContextFunction.md, docs/router/api/router/createLazyRouteFunction.md