entry.client.tsx file purpose
The entry.client.tsx file is the entry point for the browser and is responsible for hydrating the markup generated by the server. It is the first piece of code that runs in the browser, where you can initialize client-side code such as client-side libraries and add client-only providers.
Reveal default entry.client.tsx with react-router CLI
You can reveal the default entry.client.tsx file by running the command: npx react-router reveal
entry.client.tsx default implementation
A typical entry.client.tsx file imports startTransition and StrictMode from React, hydrateRoot from react-dom/client, and HydratedRouter from react-router/dom. It calls startTransition with hydrateRoot, passing the document and a StrictMode-wrapped HydratedRouter component. Example: import { startTransition, StrictMode } from "react"; import { hydrateRoot } from "react-dom/client"; import { HydratedRouter } from "react-router/dom"; startTransition(() => { hydrateRoot( document, <StrictMode> <HydratedRouter /> </StrictMode> ); });
entry.client.tsx is optional
The entry.client.tsx file is optional. By default, React Router will handle hydrating your app on the client for you without requiring this file.
Client modules with browser-only libraries example
Example of importing and wrapping a browser-only analytics library in a .client module:
```ts
// app/analytics.client.ts
import { track } from "some-browser-only-analytics-lib";
export function trackEvent(eventName: string, data: any) {
track(eventName, data);
}
```
This prevents the analytics library from being included in the server bundle.
Client module exports are undefined on server
All values exported from `.client` modules are undefined when accessed on the server. Client-only code should only be used in useEffect hooks or user event handlers where server execution does not occur.
.client directory naming convention
Nest files within `.client/` directories to mark entire directories as client-only. All files within a `.client/` directory are excluded from server bundles.
.client file naming convention
Use the `.client.ts` or `.client.tsx` suffix on file names to mark individual files as client-only. These files are excluded from server bundles and will not be executed on the server.
Client modules with browser APIs example
Example of browser feature detection in a .client module:
```ts
// app/utils/browser.client.ts
export const canUseDOM = typeof window !== "undefined";
export const hasWebGL = !!window.WebGLRenderingContext;
export const supportsVibrationAPI =
"vibrate" in window.navigator;
```
This shows using typeof checks and navigator API access safely in a client-only file.
Using client modules in components example
Example of safely using .client modules in a route component:
```tsx
// app/routes/dashboard.tsx
import { useEffect } from "react";
import {
canUseDOM,
supportsLocalStorage,
supportsVibrationAPI,
} from "../utils/browser.client.ts";
import { trackEvent } from "../analytics.client.ts";
export default function Dashboard() {
useEffect(() => {
if (canUseDOM && supportsVibrationAPI) {
console.log("Device supports vibration");
}
const savedTheme = supportsLocalStorage.getItem("theme");
if (savedTheme) {
document.body.className = savedTheme;
}
trackEvent("dashboard_viewed", {
timestamp: Date.now(),
});
}, []);
return <div>Dashboard</div>;
}
```
Client module values are accessed safely within useEffect to avoid server execution issues.
Framework conventions documentation location
Framework conventions are documented at the React Router API reference under a dedicated 'Framework Conventions' section with order index 3.
buildDirectory option
The buildDirectory option specifies the path to the build directory, relative to the project. It defaults to 'build' if not specified.
allowedActionOrigins option
The allowedActionOrigins option is an array of allowed origin hosts for action submissions to UI routes (does not apply to resource routes). It supports micromatch glob patterns where * matches one segment and ** matches multiple segments. It can be set statically in the config or at runtime by modifying the server build.
appDirectory option
The appDirectory option specifies the path to the app directory, relative to the root directory. It defaults to 'app' if not specified.
basename option
The basename option sets the React Router app basename. It defaults to '/' if not specified.
buildEnd option
The buildEnd option is a function that is called after the full React Router build is complete. It receives an object with properties buildManifest, reactRouterConfig, and viteConfig as parameters.
future option
The future option allows you to enable future flags for opting into upcoming features in React Router.
prerender option formats
The prerender option is an array of URLs to prerender to HTML files at build time. It can be specified as a static array of strings, an async function that returns an array of strings, or an object with a paths array and a concurrency number for concurrent pre-rendering.
presets option
The presets option is an array of React Router plugin config presets to ease integration with other platforms and tools.
routeDiscovery option
The routeDiscovery option configures how routes are discovered and loaded by the client. It defaults to mode: 'lazy' with manifestPath: '/__manifest'. When mode is 'lazy', routes are discovered as the user navigates and you can set a custom manifestPath for manifest requests. When mode is 'initial', all routes are included in the initial manifest.
serverBuildFile option
The serverBuildFile option specifies the file name of the server build output. The file must end in a .js extension and should be deployed to your server. It defaults to 'index.js' if not specified.
serverBundles option
The serverBundles option is a function for assigning routes to different server bundles. The function receives an object with a branch property (array of routes) and should return a server bundle ID which will be used as the bundle's directory name within the server build directory.
serverModuleFormat option
The serverModuleFormat option specifies the output format of the server build. It can be 'esm' or 'cjs', and defaults to 'esm'.
ssr option
The ssr option controls whether React Router will server render your application. If true (the default), the application is server-rendered. If false, React Router will pre-render your application as an index.html file with your assets, allowing deployment as a SPA without server-rendering.
react-router.config.ts basic example
import type { Config } from "@react-router/dev/config";
export default {
appDirectory: "app",
buildDirectory: "build",
ssr: true,
prerender: ["/", "/about"],
} satisfies Config;
react-router.config.ts file purpose
The react-router.config.ts file is an optional configuration file that lets you customize aspects of your React Router application like server-side rendering, directory locations, and build settings. It exports a default object that satisfies the Config type from @react-router/dev/config.
entry.server.tsx streamTimeout export
You can export an optional streamTimeout value (in milliseconds) that controls the amount of time the server will wait for streamed promises to settle before rejecting outstanding promises and closing the stream. It is recommended to set the React rendering timeout to a higher value than streamTimeout so it has time to stream down the underlying rejections.
entry.server.tsx handleDataRequest example
Example of handleDataRequest in entry.server.tsx:
```tsx
export function handleDataRequest(
response: Response,
{
request,
params,
context,
}: LoaderFunctionArgs | ActionFunctionArgs,
) {
response.headers.set("X-Custom-Header", "value");
return response;
}
```
This example shows how to modify a data response by adding a custom header.
entry.server.tsx handleDataRequest export
You can export an optional handleDataRequest function with signature (response: Response, { request, params, context }: LoaderFunctionArgs | ActionFunctionArgs) that allows you to modify the response of data requests. Data requests do not render HTML but rather return loader and action data to the browser after client-side hydration has occurred.
entry.server.tsx request.signal.aborted check
When implementing handleError, you should check !request.signal.aborted before logging errors. React Router's cancellation and race-condition handling can cause many requests to be aborted, and logging these aborted request errors is generally not useful.
Reveal default entry.server.tsx in Node
When running React Router in Node, you can reveal the default entry.server.tsx file using the command: npx react-router reveal
entry.server.tsx purpose and role
The entry.server.tsx file is the server-side entry point that controls how a React Router application generates HTTP responses on the server. It should render markup using a ServerRouter element with the context and url for the current request. This file is optional when running on Node (a default implementation will be used), but required for other runtimes like Cloudflare.
entry.server.tsx default export function signature
The default export of entry.server.tsx is a function that takes four parameters: request (Request), responseStatusCode (number), responseHeaders (Headers), and routerContext (EntryContext). It should return a Promise that resolves to a Response object.
entry.server.tsx streamTimeout example
Example of using streamTimeout in entry.server.tsx:
```tsx
// Reject all pending promises from handler functions after 10 seconds
export const streamTimeout = 10000;
export default function handleRequest(...) {
return new Promise((resolve, reject) => {
// ...
const { pipe, abort } = renderToPipeableStream(
<ServerRouter context={routerContext} url={request.url} />,
{ /* ... */ }
);
// Abort the streaming render pass after 11 seconds to allow the rejected
// boundaries to be flushed
setTimeout(abort, streamTimeout + 1000);
});
}
```
This example shows setting a 10-second stream timeout and aborting the renderer 1 second later to allow rejected boundaries to be flushed.
entry.server.tsx default export example
Example of a default export in entry.server.tsx:
```tsx
import { PassThrough } from "node:stream";
import type { EntryContext } from "react-router";
import { createReadableStreamFromReadable } from "@react-router/node";
import { ServerRouter } from "react-router";
import { renderToPipeableStream } from "react-dom/server";
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
routerContext: EntryContext,
) {
return new Promise((resolve, reject) => {
const { pipe, abort } = renderToPipeableStream(
<ServerRouter
context={routerContext}
url={request.url}
/>,
{
onShellReady() {
responseHeaders.set("Content-Type", "text/html");
const body = new PassThrough();
const stream =
createReadableStreamFromReadable(body);
resolve(
new Response(stream, {
headers: responseHeaders,
status: responseStatusCode,
}),
);
pipe(body);
},
onShellError(error: unknown) {
reject(error);
},
},
);
});
}
```
This example shows how to render a React Router application on the server with streaming support, setting headers and status code on the response.
entry.server.tsx handleError export
You can export an optional handleError function with signature (error: unknown, { request, params, context }: LoaderFunctionArgs | ActionFunctionArgs) that gives you control over error logging and allows you to report errors to external services. By default, React Router logs encountered server-side errors to the console, but exporting handleError disables the built-in error logging.
entry.server.tsx handleError example
Example of handleError in entry.server.tsx:
```tsx
export function handleError(
error: unknown,
{
request,
params,
context,
}: LoaderFunctionArgs | ActionFunctionArgs,
) {
if (!request.signal.aborted) {
sendErrorToErrorReportingService(error);
console.error(formatErrorForJsonLogging(error));
}
}
```
This example shows how to send errors to an external service and log them, while avoiding logging when the request was aborted.
entry.server.tsx handleError pitfall with streaming errors
When streaming HTML responses via renderToPipeableStream or renderToReadableStream, the handleError function only handles errors encountered during the initial shell render. Errors during subsequent streamed rendering must be handled manually in the onError callback since the React Router server has already sent the Response by that point.
entry.server.tsx handleError does not catch thrown Responses
The handleError function does not handle thrown Response instances from loader/action functions. It is intended to catch unexpected errors that result from bugs in code. When you intentionally throw a Response (like 401/404) from a loader/action, that is an expected flow handled by your code. If you want to log thrown Responses or send them to an external service, that should be done at the time you throw the response, not in handleError.
Layout component used for multiple exports
The Layout component wraps three different scenarios: the default root component export, HydrateFallback, and ErrorBoundary. This unified wrapper prevents React from re-mounting the app shell during transitions between these states.
root.tsx is the required root route
The root route file (app/root.tsx) is the only required route in a React Router application. It is the parent to all routes and is responsible for rendering the root HTML document.
root.tsx basic structure with Outlet and Scripts
The root route must render the HTML document with an Outlet component for child routes and a Scripts component for script tags. Example: import { Outlet, Scripts } from 'react-router'; export default function App() { return (<html lang='en'><head><link rel='icon' href='/favicon.ico' /></head><body><Outlet /><Scripts /></body></html>); }
Document-level components for root route
React Router provides several document-level components to be used once in the root route: Outlet (renders child routes), Scripts (renders script tags), and ScrollRestoration (manages scroll position for client-side transitions).
Layout export for root route
The root route supports an optional Layout export that wraps the root component, HydrateFallback, and ErrorBoundary. The Layout component takes a single children prop containing the default export, HydrateFallback, or ErrorBoundary. Layout prevents duplicating the document app shell and prevents React from re-mounting app shell elements when switching between these states.
Layout export example with children prop
Example of Layout export: export function Layout({ children }) { return (<html lang='en'><head><meta charSet='utf-8' /><meta name='viewport' content='width=device-width, initial-scale=1' /><Meta /><Links /></head><body>{children}<Scripts /><ScrollRestoration /></body></html>); }
useLoaderData not permitted in Layout or ErrorBoundary
useLoaderData cannot be used in ErrorBoundary or Layout components because they render in both success and error flows. If the loader threw an error, useLoaderData would fail since it assumes the loader ran successfully. Use useRouteLoaderData instead, which accounts for loader data potentially being undefined.
useRouteLoaderData and useRouteError for Layout logic
To fork logic in the Layout component based on request success or error, use useRouteLoaderData('root') to conditionally access loader data and useRouteError() to access error information.
Layout component must be defensive about errors
The Layout component should be very defensive to ensure it can render the ErrorBoundary without encountering render errors. If Layout throws an error while rendering the boundary, it cannot be used and the UI will fall back to the minimal built-in default ErrorBoundary.
nonce prop for ScrollRestoration and Scripts with CSP
If using a nonce-based content security policy for scripts, provide the nonce prop to both ScrollRestoration and Scripts components. Otherwise, omit the nonce prop.
routes.ts file is required configuration
The routes.ts file is required in React Router framework mode. It is a configuration file that maps URL patterns to route modules in your application.
.server module use case: database credentials
Server-only modules are appropriate for modules that contain database connection code and credentials that should never be exposed to the client, such as PrismaClient initialization with DATABASE_URL environment variables.
.server modules cannot be used for route modules
Route modules must not be marked as `.server` or `.client` because they have special handling and need to be referenced in both server and client module graphs. Attempting to mark route modules with these suffixes will cause build errors.
.server modules used in action functions
Server-only modules exported from `.server` files can be safely imported and used within action functions and other server-only code. For example, authentication utilities from `auth.server.ts` can be imported in route modules and called within an `action` function.
.server directory naming convention
Entire directories can be marked as server-only by adding `.server` to the directory name (e.g., `.server/`). All files within a `.server` directory are treated as server-only modules.
.server module naming convention
Server-only modules are marked with a `.server` suffix in the filename (e.g., `auth.server.ts`, `database.server.ts`). These modules are excluded from client bundles and only run on the server. The build will fail if any code in a `.server` file accidentally ends up in the client module graph.
.server module use case: authentication utilities
Server-only modules are appropriate for authentication logic that uses secrets like JWT_SECRET, including password hashing with bcrypt, token creation, and token verification functions.
ServerRouter purpose
ServerRouter is the server entry point for a React Router app in Framework Mode. This component is used to generate the HTML in the response from the server. It is used in entry.server.tsx.
React Router framework routers documentation index
This is the documentation index for framework routers in React Router. It is ordered as item 4 in the documentation structure.
React Router hooks documentation overview
React Router provides hooks for functional components. The hooks documentation is the second section in the API reference, after the main API documentation.
useActionData modes
useActionData is available in both framework and data modes.