From 6a4bfcce47f2ebbd6008563a160f721f0d0cb73c Mon Sep 17 00:00:00 2001 From: Brooks Lybrand Date: Fri, 13 Dec 2024 13:55:35 -0600 Subject: [PATCH] Add entry.client and entry.server (with renderToReadableStream) --- app/entry.client.tsx | 12 +++++++++++ app/entry.server.tsx | 48 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 app/entry.client.tsx create mode 100644 app/entry.server.tsx diff --git a/app/entry.client.tsx b/app/entry.client.tsx new file mode 100644 index 0000000..08ab4ec --- /dev/null +++ b/app/entry.client.tsx @@ -0,0 +1,12 @@ +import { startTransition, StrictMode } from "react"; +import { hydrateRoot } from "react-dom/client"; +import { HydratedRouter } from "react-router/dom"; + +startTransition(() => { + hydrateRoot( + document, + + + + ); +}); diff --git a/app/entry.server.tsx b/app/entry.server.tsx new file mode 100644 index 0000000..28eaedf --- /dev/null +++ b/app/entry.server.tsx @@ -0,0 +1,48 @@ +import type { EntryContext } from "react-router"; +import { ServerRouter } from "react-router"; +import { isbot } from "isbot"; +import { renderToReadableStream } from "react-dom/server"; + +const ABORT_DELAY = 5_000; + +export default async function handleRequest( + request: Request, + responseStatusCode: number, + responseHeaders: Headers, + routerContext: EntryContext +) { + let shellRendered = false; + const userAgent = request.headers.get("user-agent"); + + const body = await renderToReadableStream( + , + { + 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); + } + }, + } + ); + shellRendered = true; + + // Ensure requests from bots and SPA Mode renders wait for all content to load before responding + // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation + if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) { + await body.allReady; + } + + responseHeaders.set("Content-Type", "text/html"); + return new Response(body, { + headers: responseHeaders, + status: responseStatusCode, + }); +}