Render SSR with renderToReadableStream

This commit is contained in:
Kalle
2026-10-24 18:34:00 +03:00
parent 859ba77556
commit ef830f2b5a

View File

@@ -1,8 +1,6 @@
import { PassThrough } from "node:stream";
import { createReadableStreamFromReadable } from "@react-router/node";
import { isbot } from "isbot";
import cron from "node-cron";
import { renderToPipeableStream } from "react-dom/server";
import { renderToReadableStream } from "react-dom/server";
import { I18nextProvider } from "react-i18next";
import {
type EntryContext,
@@ -45,47 +43,33 @@ async function handleRequest(
responseHeaders.set("Cache-Control", DEFAULT_CACHE_CONTROL);
}
const callbackName = isbot(request.headers.get("user-agent"))
? "onAllReady"
: "onShellReady";
const instance = getI18nInstance(loadContext);
return new Promise((resolve, reject) => {
let didError = false;
let didError = false;
const body = await renderToReadableStream(
<I18nextProvider i18n={instance}>
<ServerRouter context={reactRouterContext} url={request.url} />
</I18nextProvider>,
{
// +1s gives React time to flush the rejected boundary contents
signal: AbortSignal.timeout(streamTimeout + 1000),
onError(error: unknown) {
didError = true;
const { pipe, abort } = renderToPipeableStream(
<I18nextProvider i18n={instance}>
<ServerRouter context={reactRouterContext} url={request.url} />
</I18nextProvider>,
{
[callbackName]: () => {
const body = new PassThrough();
const stream = createReadableStreamFromReadable(body);
responseHeaders.set("Content-Type", "text/html");
resolve(
new Response(stream, {
headers: responseHeaders,
status: didError ? 500 : responseStatusCode,
}),
);
pipe(body);
},
onShellError(error: unknown) {
reject(error);
},
onError(error: unknown) {
didError = true;
logger.error(error);
},
logger.error(error);
},
);
},
);
// +1s gives React time to flush the rejected boundary contents
setTimeout(abort, streamTimeout + 1000);
if (isbot(request.headers.get("user-agent"))) {
await body.allReady;
}
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
return new Response(body, {
headers: responseHeaders,
status: didError ? 500 : responseStatusCode,
});
}