Skip to content

Commit ec8f3ba

Browse files
TkDodoroduyemi
authored andcommitted
feat: createServerEntry (TanStack#5859)
1 parent 391d7fb commit ec8f3ba

File tree

3 files changed

+41
-33
lines changed

3 files changed

+41
-33
lines changed

docs/start/framework/react/guide/server-entry-point.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,29 @@ title: Server Entry Point
88
> [!NOTE]
99
> 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.
1010
11-
This is done via the `src/server.ts` file.
11+
The Server Entry Point supports the universal fetch handler format, commonly used by [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/) and other WinterCG-compatible runtimes.
1212

13-
```tsx
14-
// src/server.ts
15-
import handler, { type ServerEntry } from '@tanstack/react-start/server-entry'
13+
To ensure interoperability, the default export must conform to our `ServerEntry` interface:
1614

15+
```ts
1716
export default {
18-
fetch(request) {
19-
return handler.fetch(request)
17+
fetch(req: Request, opts?: RequestOptions): Response | Promise<Response> {
18+
// ...
2019
},
21-
} satisfies ServerEntry
20+
}
2221
```
2322

24-
The default export must conform to the `ServerEntry` interface:
23+
TanStack Start exposes a wrapper to make creation type-safe. This is done in the `src/server.ts` file.
2524

26-
```ts
27-
export default {
28-
fetch(req: Request, opts?: RequestOptions): Promise<Response> {
29-
// ...
25+
```tsx
26+
// src/server.ts
27+
import handler, { createServerEntry } from '@tanstack/react-start/server-entry'
28+
29+
export default createServerEntry({
30+
fetch(request) {
31+
return handler.fetch(request)
3032
},
31-
}
33+
})
3234
```
3335

3436
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.
@@ -44,7 +46,7 @@ import {
4446
defaultStreamHandler,
4547
defineHandlerCallback,
4648
} from '@tanstack/react-start/server'
47-
import type { ServerEntry } from '@tanstack/react-start/server-entry'
49+
import { createServerEntry } from '@tanstack/react-start/server-entry'
4850

4951
const customHandler = defineHandlerCallback((ctx) => {
5052
// add custom logic here
@@ -53,9 +55,9 @@ const customHandler = defineHandlerCallback((ctx) => {
5355

5456
const fetch = createStartHandler(customHandler)
5557

56-
export default {
58+
export default createServerEntry({
5759
fetch,
58-
} satisfies ServerEntry
60+
})
5961
```
6062

6163
## Request context
@@ -65,7 +67,7 @@ When your server needs to pass additional, typed data into request handlers (for
6567
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:
6668

6769
```tsx
68-
import handler, { type ServerEntry } from '@tanstack/react-start/server-entry'
70+
import handler, { createServerEntry } from '@tanstack/react-start/server-entry'
6971

7072
type MyRequestContext = {
7173
hello: string
@@ -80,11 +82,11 @@ declare module '@tanstack/react-start' {
8082
}
8183
}
8284

83-
export default {
85+
export default createServerEntry({
8486
async fetch(request) {
8587
return handler.fetch(request, { context: { hello: 'world', foo: 123 } })
8688
},
87-
} satisfies ServerEntry
89+
})
8890
```
8991

9092
## Server Configuration

packages/react-start/src/default-entry/server.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ import type { RequestHandler } from '@tanstack/react-start/server'
77

88
const fetch = createStartHandler(defaultStreamHandler)
99

10-
const serverEntry = {
11-
// Providing `RequestHandler` from `@tanstack/react-start/server` is required so that the output types don't import it from `@tanstack/start-server-core`
12-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
13-
fetch: fetch as RequestHandler<Register>,
14-
} as const
10+
// Providing `RequestHandler` from `@tanstack/react-start/server` is required so that the output types don't import it from `@tanstack/start-server-core`
11+
export type ServerEntry = { fetch: RequestHandler<Register> }
1512

16-
export type ServerEntry = typeof serverEntry
13+
export function createServerEntry(entry: ServerEntry): ServerEntry {
14+
return {
15+
async fetch(...args) {
16+
return await entry.fetch(...args)
17+
},
18+
}
19+
}
1720

18-
export default serverEntry
21+
export default createServerEntry({ fetch })

packages/solid-start/src/default-entry/server.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ import type { RequestHandler } from '@tanstack/solid-start/server'
77

88
const fetch = createStartHandler(defaultStreamHandler)
99

10-
const serverEntry = {
11-
// Providing `RequestHandler` from `@tanstack/solid-start/server` is required so that the output types don't import it from `@tanstack/start-server-core`
12-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
13-
fetch: fetch as RequestHandler<Register>,
14-
} as const
10+
// Providing `RequestHandler` from `@tanstack/solid-start/server` is required so that the output types don't import it from `@tanstack/start-server-core`
11+
export type ServerEntry = { fetch: RequestHandler<Register> }
1512

16-
export type ServerEntry = typeof serverEntry
13+
export function createServerEntry(entry: ServerEntry): ServerEntry {
14+
return {
15+
async fetch(...args) {
16+
return await entry.fetch(...args)
17+
},
18+
}
19+
}
1720

18-
export default serverEntry
21+
export default createServerEntry({ fetch })

0 commit comments

Comments
 (0)