From db5e176f515e55b93f914c6064b3a2d74eb316f2 Mon Sep 17 00:00:00 2001 From: TkDodo Date: Wed, 29 Oct 2025 15:13:59 +0100 Subject: [PATCH 1/2] feat: export type ServerEntry to allow typing of default exports when creating a custom server handler --- .../framework/react/guide/observability.md | 5 +++-- .../react/guide/server-entry-point.md | 21 ++++++++++--------- .../react-start/src/default-entry/server.ts | 8 +++++-- .../solid-start/src/default-entry/server.ts | 8 +++++-- packages/solid-start/src/server.tsx | 1 + 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/docs/start/framework/react/guide/observability.md b/docs/start/framework/react/guide/observability.md index 8565730a891..c2c73e2f60f 100644 --- a/docs/start/framework/react/guide/observability.md +++ b/docs/start/framework/react/guide/observability.md @@ -519,6 +519,7 @@ import { defaultStreamHandler, defineHandlerCallback, } from '@tanstack/react-start/server' +import type { ServerEntry } from '@tanstack/react-start/server-entry' const customHandler = defineHandlerCallback(async (ctx) => { // We do this so that transactions are grouped under the route ID instead of unique URLs @@ -538,11 +539,11 @@ const customHandler = defineHandlerCallback(async (ctx) => { }) export default { - fetch(request: Request) { + fetch(request) { const handler = createStartHandler(customHandler) return handler(request) }, -} +} satisfies ServerEntry ``` ```bash diff --git a/docs/start/framework/react/guide/server-entry-point.md b/docs/start/framework/react/guide/server-entry-point.md index a54add2db4a..e80a3dc292b 100644 --- a/docs/start/framework/react/guide/server-entry-point.md +++ b/docs/start/framework/react/guide/server-entry-point.md @@ -12,20 +12,20 @@ This is done via the `src/server.ts` file. ```tsx // src/server.ts -import handler from '@tanstack/react-start/server-entry' +import handler, { type ServerEntry } from '@tanstack/react-start/server-entry' export default { - fetch(request: Request) { + fetch(request) { return handler.fetch(request) }, -} +} satisfies ServerEntry ``` -The entry point must conform to the following interface: +The default export must conform to the `ServerEntry` interface: -```tsx +```ts export default { - fetch(req: Request): Promise { + fetch(req: Request, opts?: RequestOptions): Promise { // ... }, } @@ -44,6 +44,7 @@ import { defaultStreamHandler, defineHandlerCallback, } from '@tanstack/react-start/server' +import type { ServerEntry } from '@tanstack/react-start/server-entry' const customHandler = defineHandlerCallback((ctx) => { // add custom logic here @@ -54,7 +55,7 @@ const fetch = createStartHandler(customHandler) export default { fetch, -} +} satisfies ServerEntry ``` ## Request context @@ -64,7 +65,7 @@ When your server needs to pass additional, typed data into request handlers (for To add types for your request context, augment the `Register` interface from `@tanstack/react-start` with a `server.requestContext` property. The runtime `context` you pass to `handler.fetch` will then match that type. Example: ```tsx -import handler from '@tanstack/react-start/server-entry' +import handler, { type ServerEntry } from '@tanstack/react-start/server-entry' type MyRequestContext = { hello: string @@ -80,10 +81,10 @@ declare module '@tanstack/react-start' { } export default { - async fetch(request: Request): Promise { + async fetch(request) { return handler.fetch(request, { context: { hello: 'world', foo: 123 } }) }, -} +} satisfies ServerEntry ``` ## Server Configuration diff --git a/packages/react-start/src/default-entry/server.ts b/packages/react-start/src/default-entry/server.ts index 9d3d861a972..d24e2c4888b 100644 --- a/packages/react-start/src/default-entry/server.ts +++ b/packages/react-start/src/default-entry/server.ts @@ -7,8 +7,12 @@ import type { RequestHandler } from '@tanstack/react-start/server' const fetch = createStartHandler(defaultStreamHandler) -export default { +const serverEntry = { // Providing `RequestHandler` from `@tanstack/react-start/server` is required so that the output types don't import it from `@tanstack/start-server-core` // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion fetch: fetch as RequestHandler, -} +} as const + +export type ServerEntry = typeof serverEntry + +export default serverEntry diff --git a/packages/solid-start/src/default-entry/server.ts b/packages/solid-start/src/default-entry/server.ts index 023521f207f..d83d67e1e21 100644 --- a/packages/solid-start/src/default-entry/server.ts +++ b/packages/solid-start/src/default-entry/server.ts @@ -7,8 +7,12 @@ import type { RequestHandler } from '@tanstack/solid-start/server' const fetch = createStartHandler(defaultStreamHandler) -export default { +const serverEntry = { // Providing `RequestHandler` from `@tanstack/solid-start/server` is required so that the output types don't import it from `@tanstack/start-server-core` // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion fetch: fetch as RequestHandler, -} +} as const + +export type ServerEntry = typeof serverEntry + +export default serverEntry diff --git a/packages/solid-start/src/server.tsx b/packages/solid-start/src/server.tsx index 5e6da97d48d..5198010fc50 100644 --- a/packages/solid-start/src/server.tsx +++ b/packages/solid-start/src/server.tsx @@ -1 +1,2 @@ export * from '@tanstack/solid-start-server' +export type { ServerEntry } from './default-entry/server' From 93bc7503451a806fadf75fa395e61b8d36cf1bdd Mon Sep 17 00:00:00 2001 From: TkDodo Date: Wed, 29 Oct 2025 15:31:49 +0100 Subject: [PATCH 2/2] ref: only export from server-entry --- packages/solid-start/src/server.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/solid-start/src/server.tsx b/packages/solid-start/src/server.tsx index 5198010fc50..5e6da97d48d 100644 --- a/packages/solid-start/src/server.tsx +++ b/packages/solid-start/src/server.tsx @@ -1,2 +1 @@ export * from '@tanstack/solid-start-server' -export type { ServerEntry } from './default-entry/server'