diff --git a/app/entry.server.tsx b/app/entry.server.tsx
index 0ef515b81..4c3ffcfde 100644
--- a/app/entry.server.tsx
+++ b/app/entry.server.tsx
@@ -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(
+
+
+ ,
+ {
+ // +1s gives React time to flush the rejected boundary contents
+ signal: AbortSignal.timeout(streamTimeout + 1000),
+ onError(error: unknown) {
+ didError = true;
- const { pipe, abort } = renderToPipeableStream(
-
-
- ,
- {
- [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,
});
}