import { PassThrough } from 'node:stream' import { createReadableStreamFromReadable } from '@react-router/node' import { renderToPipeableStream } from 'react-dom/server' import type { AppLoadContext, EntryContext } from 'react-router' import { ServerRouter } from 'react-router' export default function handleRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, reactRouterContext: EntryContext, loadContext: AppLoadContext, ) { return handleBrowserRequest( request, responseStatusCode, responseHeaders, reactRouterContext, ) } function handleBrowserRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, reactRouterContext: EntryContext, ) { return new Promise((resolve, reject) => { let shellRendered = false const { pipe, abort } = renderToPipeableStream( , { onShellReady() { shellRendered = true 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: unknown) { reject(error) }, onError(error: unknown) { responseStatusCode = 500 // Log streaming rendering errors from inside the shell. Don't log // errors encountered during initial shell rendering since they'll // reject and get logged in handleDocumentRequest. if (shellRendered) { console.error(error) } }, }, ) setTimeout(abort, 5000) }) }