| name | tanstack-start |
| description | TanStack Start full-stack React framework. Covers file-based routing, SSR, data loading, and server functions. Triggers on tanstack start, createFileRoute, loader. |
| triggers | tanstack start, createFileRoute, createRootRoute, loader, serverFn, ssr |
MCPSearch({ query: "select:mcp__plugin_devtools_context7__query-docs" })
// TanStack Start patterns
mcp__context7__query_docs({
libraryId: "/tanstack/start",
query: "How do I use createFileRoute with loader and serverFn?",
});
// SSR and streaming
mcp__context7__query_docs({
libraryId: "/tanstack/start",
query: "How do I implement SSR, streaming, and deferred loading?",
});
// Server functions
mcp__context7__query_docs({
libraryId: "/tanstack/start",
query: "How do I use createServerFn and server actions?",
});
Note: Context7 v2 uses server-side filtering. Use descriptive natural language queries.
// routes/dashboard.tsx
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/dashboard")({
loader: async () => {
const data = await fetchDashboardData();
return { data };
},
component: DashboardPage,
});
function DashboardPage() {
const { data } = Route.useLoaderData();
return <Dashboard data={data} />;
}
Root route with layout:
// routes/__root.tsx
import { createRootRoute, Outlet } from "@tanstack/react-router";
export const Route = createRootRoute({
component: () => (
<html>
<body>
<Header />
<Outlet />
<Footer />
</body>
</html>
),
});
Server function:
import { createServerFn } from "@tanstack/react-start/server";
const getUser = createServerFn({ method: "GET" })
.validator((userId: string) => userId)
.handler(async ({ data: userId }) => {
return await db.query.users.findFirst({
where: eq(users.id, userId),
});
});
// Usage in component
const user = await getUser({ data: userId });
// routes/users/$userId.tsx
export const Route = createFileRoute("/users/$userId")({
loader: async ({ params }) => {
return await getUser(params.userId);
},
});
Nested layouts:
// routes/_authenticated.tsx (layout route)
export const Route = createFileRoute("/_authenticated")({
beforeLoad: async ({ context }) => {
if (!context.session) {
throw redirect({ to: "/login" });
}
},
component: AuthenticatedLayout,
});
// routes/_authenticated/settings.tsx (nested under layout)
export const Route = createFileRoute("/_authenticated/settings")({
component: SettingsPage,
});
Search params:
import { z } from "zod";
const searchSchema = z.object({
page: z.number().optional().default(1),
search: z.string().optional(),
});
export const Route = createFileRoute("/products")({
validateSearch: searchSchema,
component: ProductsPage,
});
function ProductsPage() {
const { page, search } = Route.useSearch();
}
export const Route = createFileRoute("/dashboard")({
loader: async ({ context }) => {
const { queryClient, session } = context;
return queryClient.ensureQueryData({
queryKey: ["dashboard", session.userId],
queryFn: () => fetchDashboard(session.userId),
});
},
});
Deferred data (streaming):
export const Route = createFileRoute("/analytics")({
loader: async () => {
return {
// Critical data - awaited
summary: await fetchSummary(),
// Non-critical - streamed
details: fetchDetails(), // Returns promise
};
},
});
function AnalyticsPage() {
const { summary, details } = Route.useLoaderData();
return (
<div>
<Summary data={summary} />
<Suspense fallback={<Skeleton />}>
<Await promise={details}>
{(data) => <Details data={data} />}
</Await>
</Suspense>
</div>
);
}
src/
├── routes/
│ ├── __root.tsx # Root layout
│ ├── index.tsx # /
│ ├── _authenticated.tsx # Layout route (prefix _)
│ ├── _authenticated/
│ │ ├── dashboard.tsx # /_authenticated/dashboard
│ │ └── settings.tsx # /_authenticated/settings
│ ├── users/
│ │ ├── index.tsx # /users
│ │ └── $userId.tsx # /users/:userId
│ └── api/
│ └── [...].ts # API routes
├── router.tsx # Router configuration
└── entry-server.tsx # Server entry
Naming:
- Layout routes: prefix with
_(e.g.,_authenticated.tsx) - Dynamic params: prefix with
$(e.g.,$userId.tsx) - Catch-all:
[...].tsx
- Context7 docs fetched for current API
- Routes use
createFileRoute - Loaders fetch data server-side
- Search params validated with Zod
- Layouts use
Outletfor children