1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import type { AppLoadContext, EntryContext } from "@remix-run/cloudflare";
import { RemixServer } from "@remix-run/react";
import * as isbotModule from "isbot";
import { renderToReadableStream } from "react-dom/server";
export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
loadContext: AppLoadContext
) {
const body = await renderToReadableStream(
<RemixServer context={remixContext} url={request.url} />,
{
// If you wish to abort the rendering process, you can pass a signal here.
// Please refer to the templates for example son how to configure this.
// signal: controller.signal,
onError(error: unknown) {
// Log streaming rendering errors from inside the shell
console.error(error);
responseStatusCode = 500;
},
}
);
if (isBotRequest(request.headers.get("user-agent"))) {
await body.allReady;
}
responseHeaders.set("Content-Type", "text/html");
return new Response(body, {
headers: responseHeaders,
status: responseStatusCode,
});
}
// We have some Remix apps in the wild already running with isbot@3 so we need
// to maintain backwards compatibility even though we want new apps to use
// isbot@4. That way, we can ship this as a minor Semver update to @remix-run/dev.
function isBotRequest(userAgent: string | null) {
if (!userAgent) {
return false;
}
// isbot >= 3.8.0, >4
if ("isbot" in isbotModule && typeof isbotModule.isbot === "function") {
return isbotModule.isbot(userAgent);
}
// isbot < 3.8.0
if ("default" in isbotModule && typeof isbotModule.default === "function") {
return isbotModule.default(userAgent);
}
return false;
}
|