mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-27 13:06:13 -05:00
Render SSR with renderToReadableStream
This commit is contained in:
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user