import { PassThrough } from "stream"; import { Response } from "@remix-run/node"; import { RemixServer } from "@remix-run/react"; import isbot from "isbot"; import { renderToPipeableStream } from "react-dom/server"; const ABORT_DELAY = 5000; export default function handleRequest( request, responseStatusCode, responseHeaders, remixContext ) { return isbot(request.headers.get("user-agent")) ? handleBotRequest( request, responseStatusCode, responseHeaders, remixContext ) : handleBrowserRequest( request, responseStatusCode, responseHeaders, remixContext ); } function handleBotRequest( request, responseStatusCode, responseHeaders, remixContext ) { return new Promise((resolve, reject) => { let didError = false; const { pipe, abort } = renderToPipeableStream( , { onAllReady() { const body = new PassThrough(); responseHeaders.set("Content-Type", "text/html"); resolve( new Response(body, { headers: responseHeaders, status: didError ? 500 : responseStatusCode, }) ); pipe(body); }, onShellError(error) { reject(error); }, onError(error) { didError = true; console.error(error); }, } ); setTimeout(abort, ABORT_DELAY); }); } function handleBrowserRequest( request, responseStatusCode, responseHeaders, remixContext ) { return new Promise((resolve, reject) => { let didError = false; const { pipe, abort } = renderToPipeableStream( , { onShellReady() { const body = new PassThrough(); responseHeaders.set("Content-Type", "text/html"); resolve( new Response(body, { headers: responseHeaders, status: didError ? 500 : responseStatusCode, }) ); pipe(body); }, onShellError(err) { reject(err); }, onError(error) { didError = true; console.error(error); }, } ); setTimeout(abort, ABORT_DELAY); }); }