Skip to content

Commit 8a88957

Browse files
committed
Add entry.client and entry.server (with renderToReadableStream)
1 parent 7001f2d commit 8a88957

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

app/entry.client.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { startTransition, StrictMode } from "react";
2+
import { hydrateRoot } from "react-dom/client";
3+
import { HydratedRouter } from "react-router/dom";
4+
5+
startTransition(() => {
6+
hydrateRoot(
7+
document,
8+
<StrictMode>
9+
<HydratedRouter />
10+
</StrictMode>
11+
);
12+
});

app/entry.server.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { EntryContext } from "react-router";
2+
import { ServerRouter } from "react-router";
3+
import { isbot } from "isbot";
4+
import { renderToReadableStream } from "react-dom/server";
5+
6+
const ABORT_DELAY = 5_000;
7+
8+
export default async function handleRequest(
9+
request: Request,
10+
responseStatusCode: number,
11+
responseHeaders: Headers,
12+
routerContext: EntryContext
13+
) {
14+
let shellRendered = false;
15+
const userAgent = request.headers.get("user-agent");
16+
17+
const body = await renderToReadableStream(
18+
<ServerRouter
19+
context={routerContext}
20+
url={request.url}
21+
abortDelay={ABORT_DELAY}
22+
/>,
23+
{
24+
onError(error: unknown) {
25+
responseStatusCode = 500;
26+
// Log streaming rendering errors from inside the shell. Don't log
27+
// errors encountered during initial shell rendering since they'll
28+
// reject and get logged in handleDocumentRequest.
29+
if (shellRendered) {
30+
console.error(error);
31+
}
32+
},
33+
}
34+
);
35+
shellRendered = true;
36+
37+
// Ensure requests from bots and SPA Mode renders wait for all content to load before responding
38+
// https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
39+
if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) {
40+
await body.allReady;
41+
}
42+
43+
responseHeaders.set("Content-Type", "text/html");
44+
return new Response(body, {
45+
headers: responseHeaders,
46+
status: responseStatusCode,
47+
});
48+
}

0 commit comments

Comments
 (0)