Server Routes (API Endpoints)
Server routes are HTTP endpoints defined in your route files using the server property. They live alongside your page routes and follow the same file-based conventions.
Routes in this demo
File path → endpoint URL
/api/hello/api/echo/api/users/:userId/server-routesGET /api/hello
routes/api/hello.ts → GET handlerA basic GET endpoint. Reads a query parameter and returns plain text. The simplest server route possible.
GET: async ({ request }) => {
const url = new URL(request.url)
const name = url.searchParams.get('name') || 'World'
return new Response(`Hello, ${name}!`)
}POST /api/hello
routes/api/hello.ts → POST handlerSame file, different HTTP method. Parses JSON body with request.json() and returns a JSON response using Response.json().
POST: async ({ request }) => {
const body = await request.json()
return Response.json({
message: `Hello, ${body.name}!`,
receivedAt: new Date().toISOString(),
})
}POST /api/echo
routes/api/echo.ts → POST handlerEchoes back the request body, content type, method, and URL. Demonstrates reading request headers and setting custom response headers.
GET /api/users/:userId
routes/api/users/$userId.ts → GET handlerDynamic path params work the same as page routes. The $userId segment is captured and available via params.userId. Try IDs 1-3 for valid users, anything else for a 404.
GET: async ({ params }) => {
const user = mockUsers[params.userId]
if (!user) {
return Response.json(
{ error: 'User not found', userId: params.userId },
{ status: 404 },
)
}
return Response.json(user)
}Combined: server handler + component
routes/server-routes.tsx → POST handler + componentThis page itself has a POST server handler. The same file defines both the UI component you're reading and an API endpoint. Browser navigation renders the component; a POST request hits the handler.
export const Route = createFileRoute('/server-routes')({
server: {
handlers: {
POST: async ({ request }) => {
const body = await request.json()
return Response.json({ message: '...', received: body })
},
},
},
component: ServerRoutesPage, // Same file!
})File conventions
Same rules as page routesServer routes follow the same file-based naming as TanStack Router page routes.
| File | Endpoint | Type |
|---|---|---|
| api/hello.ts | /api/hello | Static |
| api/users/$id.ts | /api/users/:id | Dynamic param |
| api/file/$.ts | /api/file/* | Wildcard (splat) |
| feed[.]json.ts | /feed.json | Escaped dot |
| page.tsx | /page | Combined (handler + component) |
Server routes vs server functions: Use server routes when you need raw HTTP endpoints (webhooks, APIs, file downloads). Use createServerFn when you need typed RPC calls from your components and loaders.