import { PassThrough } from "node:stream"; import { createReadableStreamFromReadable } from "@react-router/node"; import { isbot } from "isbot"; import { renderToPipeableStream } from "react-dom/server"; import { type EntryContext, ServerRouter } from "react-router"; import { addDocumentResponseHeaders } from "./shopify.server"; export const streamTimeout = 5000; export default async function handleRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, reactRouterContext: EntryContext, ) { addDocumentResponseHeaders(request, responseHeaders); const userAgent = request.headers.get("user-agent"); const callbackName = isbot(userAgent ?? "") ? "onAllReady" : "onShellReady"; return new Promise((resolve, reject) => { 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: responseStatusCode })); pipe(body); }, onShellError(error) { reject(error); }, onError(error) { responseStatusCode = 500; console.error(error); }, }); setTimeout(abort, streamTimeout + 1000); }); }