Skip to content

Commit 96a1e82

Browse files
committed
feat: add cloudflare ssr for playground
1 parent 1cbb132 commit 96a1e82

6 files changed

Lines changed: 86 additions & 2 deletions

File tree

apps/docs/app/entry.server.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React from "react";
2+
import { renderToReadableStream } from "react-dom/server";
3+
import { isbot } from "isbot";
4+
import { ServerRouter } from "react-router";
5+
6+
export const streamTimeout = 5_000;
7+
8+
export default async function handleRequest(
9+
request,
10+
responseStatusCode,
11+
responseHeaders,
12+
routerContext,
13+
) {
14+
if (request.method.toUpperCase() === "HEAD") {
15+
return new Response(null, {
16+
status: responseStatusCode,
17+
headers: responseHeaders,
18+
});
19+
}
20+
21+
let shellRendered = false;
22+
let userAgent = request.headers.get("user-agent");
23+
24+
let body = await renderToReadableStream(
25+
React.createElement(ServerRouter, {
26+
context: routerContext,
27+
url: request.url,
28+
}),
29+
{
30+
signal: AbortSignal.timeout(streamTimeout + 1_000),
31+
onError(error) {
32+
responseStatusCode = 500;
33+
if (shellRendered) {
34+
console.error(error);
35+
}
36+
},
37+
},
38+
);
39+
40+
shellRendered = true;
41+
42+
if (
43+
((userAgent && isbot(userAgent)) || routerContext.isSpaMode) &&
44+
body.allReady
45+
) {
46+
await body.allReady;
47+
}
48+
49+
responseHeaders.set("Content-Type", "text/html");
50+
51+
return new Response(body, {
52+
headers: responseHeaders,
53+
status: responseStatusCode,
54+
});
55+
}

apps/docs/functions/try.data.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { onRequest } from "../server/react-router-handler.js";

apps/docs/functions/try.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { onRequest } from "../server/react-router-handler.js";

apps/docs/react-router.config.mjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@ import * as os from "node:os";
44
const { stdlibPaths } = await import("./app/DocsRoutes.jsx");
55

66
export default {
7-
ssr: false,
7+
ssr: true,
8+
routeDiscovery: { mode: "initial" },
89

910
prerender: {
1011
concurrency: os.availableParallelism(),
1112
async paths({ getStaticPaths }) {
12-
return [...(await getStaticPaths()), ...stdlibPaths];
13+
return [
14+
...(await getStaticPaths()).filter(
15+
(path) => path !== "/try" && path !== "try",
16+
),
17+
...stdlibPaths,
18+
];
1319
},
1420
},
1521
buildEnd: async () => {
22+
fs.rmSync("./out", { recursive: true, force: true });
1623
fs.cpSync("./build/client", "./out", { recursive: true });
1724
},
1825
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { createRequestHandler } from "react-router";
2+
3+
const mode = globalThis.process?.env?.NODE_ENV ?? "production";
4+
5+
const handleReactRouterRequest = createRequestHandler(
6+
() => import("../build/server/index.js"),
7+
mode,
8+
);
9+
10+
export function onRequest(context) {
11+
return handleReactRouterRequest(context.request, {
12+
cloudflare: {
13+
env: context.env,
14+
},
15+
});
16+
}

apps/docs/wrangler.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name = "rescript-lang-org"
2+
compatibility_date = "2026-05-01"
3+
compatibility_flags = ["nodejs_compat"]
4+
pages_build_output_dir = "out"

0 commit comments

Comments
 (0)