Note
The server entry point is optional out of the box. If not provided, TanStack Start will automatically handle the server entry point for you using the below as a default.
This is done via the src/server.ts file.
// src/server.ts
import handler from '@tanstack/solid-start/server-entry'
export default {
fetch(request: Request) {
return handler.fetch(request)
},
}
// src/server.ts
import handler from '@tanstack/solid-start/server-entry'
export default {
fetch(request: Request) {
return handler.fetch(request)
},
}
The entry point must conform to the following interface:
export default {
fetch(req: Request): Promise<Response> {
// ...
},
}
export default {
fetch(req: Request): Promise<Response> {
// ...
},
}
Whether we are statically generating our app or serving it dynamically, the server.ts file is the entry point for doing all SSR-related work as well as for handling server routes and server function requests.
You can create custom server handlers to modify how your application is rendered:
// src/server.ts
import {
createStartHandler,
defaultStreamHandler,
defineHandlerCallback,
} from '@tanstack/solid-start/server'
const customHandler = defineHandlerCallback((ctx) => {
// add custom logic here
return defaultStreamHandler(ctx)
})
const fetch = createStartHandler(customHandler)
export default {
fetch,
}
// src/server.ts
import {
createStartHandler,
defaultStreamHandler,
defineHandlerCallback,
} from '@tanstack/solid-start/server'
const customHandler = defineHandlerCallback((ctx) => {
// add custom logic here
return defaultStreamHandler(ctx)
})
const fetch = createStartHandler(customHandler)
export default {
fetch,
}
When your server needs to pass additional, typed data into request handlers (for example, authenticated user info, a database connection, or per-request flags), register a request context type via TypeScript module augmentation. The registered context is delivered as the second argument to the server fetch handler and is available throughout the server-side middleware chain — including global middleware, request/function middleware, server routes, server functions, and the router itself.
To add types for your request context, augment the Register interface from @tanstack/solid-start with a server.requestContext property. The runtime context you pass to handler.fetch will then match that type. Example:
import handler from '@tanstack/solid-start/server-entry'
type MyRequestContext = {
hello: string
foo: number
}
declare module '@tanstack/solid-start' {
interface Register {
server: {
requestContext: MyRequestContext
}
}
}
export default {
async fetch(request: Request): Promise<Response> {
return handler.fetch(request, { context: { hello: 'world', foo: 123 } })
},
}
import handler from '@tanstack/solid-start/server-entry'
type MyRequestContext = {
hello: string
foo: number
}
declare module '@tanstack/solid-start' {
interface Register {
server: {
requestContext: MyRequestContext
}
}
}
export default {
async fetch(request: Request): Promise<Response> {
return handler.fetch(request, { context: { hello: 'world', foo: 123 } })
},
}
The server entry point is where you can configure server-specific behavior:
This flexibility allows you to customize how your TanStack Start application handles server-side rendering while maintaining the framework's conventions.
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.