new·Earn with mozg — 20% of every monthSend somebody here and take a fifth of every plan payment they make, for as long as they keep paying — not a bounty on the first invoice. Your handle is the link, the window is thirty days, and the commission lands on your balance the second they pay. Free to join: if you have signed in, you already have the link. mozg.sh/earnall news →
mozg.beta
Sign in

React · API reference · all subjects

react dom: server rendering

81 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Legacy streaming vs non-streaming server APIs

Streaming APIs (renderToReadableStream, renderToPipeableStream, resume, resumeToPipeableStream) are available in environments that support Web Streams or Node.js Streams. Legacy non-streaming APIs (renderToString, renderToStaticMarkup) can be used in environments that don't support streams but have limited functionality.

resume API for Web Streams

resume resumes prerender to a Readable Web Stream. This method is available in environments with Web Streams, which includes browsers, Deno, and some modern edge runtimes.

renderToPipeableStream API

renderToPipeableStream renders a React tree to a pipeable Node.js Stream. This method is only available in environments with Node.js Streams.

renderToString API

renderToString renders a React tree to a string. This method can be used in environments that don't support streams and has limited functionality compared to the streaming APIs.

renderToStaticMarkup API

renderToStaticMarkup renders a non-interactive React tree to a string. This method can be used in environments that don't support streams and has limited functionality compared to the streaming APIs.

react-dom/server APIs overview

The react-dom/server APIs let you server-side render React components to HTML. These APIs are only used on the server at the top level of your app to generate the initial HTML. A framework may call them for you. Most components don't need to import or use them.

renderToReadableStream API

renderToReadableStream renders a React tree to a Readable Web Stream. This method is available in environments with Web Streams, which includes browsers, Deno, and some modern edge runtimes.

resumeToPipeableStream API

resumeToPipeableStream resumes prerenderToNodeStream to a pipeable Node.js Stream. This method is only available in environments with Node.js Streams.

Web Streams vs Node.js Streams APIs performance note

Node.js includes Web Streams methods (renderToReadableStream and resume) for compatibility, but they are not recommended due to worse performance. Use the dedicated Node.js APIs (renderToPipeableStream and resumeToPipeableStream) instead.

resumeToPipeableStream option caveats

resumeToPipeableStream does not accept options for bootstrapScripts, bootstrapScriptContent, or bootstrapModules—these must be passed to the prerender call instead. It does not accept identifierPrefix since the prefix must be the same in both prerender and resumeToPipeableStream. nonce should only be provided if you're not providing scripts to prerender. resumeToPipeableStream re-renders from the root until it finds a component that was not fully pre-rendered; only fully prerendered components are skipped entirely.

resumeToPipeableStream signature

The signature of resumeToPipeableStream is: const {pipe, abort} = await resumeToPipeableStream(reactNode, postponedState, options?). It returns an object with two methods: pipe and abort.

resumeToPipeableStream purpose and Node.js specific usage

resumeToPipeableStream streams a pre-rendered React tree to a pipeable Node.js Stream. It is specific to Node.js. Environments with Web Streams, like Deno and modern edge runtimes, should use resume (renderToReadableStream) instead.

resumeToPipeableStream parameters

resumeToPipeableStream accepts three parameters: reactNode (the React node, expected to represent the entire document with an <html> tag), postponedState (the opaque postpone object returned from a prerender API), and optional options object. The options object can contain: nonce (string for Content-Security-Policy script-src), onAllReady (callback when all rendering is complete), onBrowserBailout (callback when recovering from browser() by leaving a Suspense fallback), onError (callback for server errors), onShellReady (callback after shell finishes), and onShellError (callback if there was an error rendering the shell).

resumeToPipeableStream return value methods

resumeToPipeableStream returns an object with two methods: pipe (outputs HTML into the provided Writable Node.js Stream, call in onShellReady to enable streaming or in onAllReady for crawlers and static generation) and abort (allows aborting server rendering and rendering the rest on the client).

resumeToPipeableStream what it is used for

resumeToPipeableStream is used to resume rendering a pre-rendered React tree as HTML into a Node.js Stream. It accepts the postponedState from a previous prerender call and continues rendering.

resume caveats

resume does not accept options for bootstrapScripts, bootstrapScriptContent, or bootstrapModules - these must be passed to the prerender call instead. resume does not accept identifierPrefix since the prefix must be the same in both prerender and resume. nonce should only be provided to resume if not providing scripts to prerender. resume re-renders from the root until it finds a component that was not fully pre-rendered; only fully prerendered components are skipped entirely.

resume signature and parameters

The resume function signature is: const stream = await resume(reactNode, postponedState, options?). The reactNode parameter is the React node to render (typically <App />), expected to render the entire document with an <html> tag. The postponedState parameter is the opaque postpone object returned from a prerender API call. The options parameter is optional and is an object with streaming options.

resume options object

The resume function accepts optional options with the following properties: nonce (string, optional) - a nonce value to allow scripts for script-src Content-Security-Policy; signal (AbortSignal, optional) - an abort signal to abort server rendering and render the rest on the client; onBrowserBailout (callback, optional, canary) - called when React recovers from browser() by leaving a Suspense fallback for the browser to replace, receives an Error and errorInfo object with componentStack; onError (callback, optional) - called whenever there is a server error (recoverable or not), defaults to console.error.

resume return value

resume returns a Promise. If resume successfully produces a shell, the Promise resolves to a Readable Web Stream that can be piped to a Writable Web Stream. If an error happens in the shell, the Promise rejects with that error. The returned stream has an additional property: allReady, a Promise that resolves when all rendering is complete, which can be awaited before returning a response for crawlers and static generation.

resume usage and dependencies

resume is used for resuming a pre-rendered React tree as HTML into a Readable Web Stream. It requires a postponedState object from a prerender API call. resume depends on Web Streams API; for Node.js environments, use resumeToNodeStream instead. The function is imported from 'react-dom/server'.

Custom error handling with instanceof checks

You can create custom Error subclasses and use instanceof to check which error type was thrown. This lets your onError, onShellReady, and onShellError callbacks handle different errors differently, such as returning different status codes for NotFoundError vs other errors.

Waiting for all content with onAllReady for crawlers

For crawlers or static generation, use onAllReady instead of onShellReady to wait for all content to load before streaming. Check an isCrawler flag: in onShellReady, only pipe if !isCrawler; in onAllReady, only pipe if isCrawler. This gives crawlers the final HTML but regular visitors get progressive loading.

Aborting server rendering with abort

You can call abort() on the returned object to force server rendering to give up after a timeout. React will flush the remaining loading fallbacks as HTML and attempt to render the rest on the client. Example: const { pipe, abort } = renderToPipeableStream(<App />, {...}); setTimeout(() => { abort(); }, 10000);

Streaming more content with Suspense boundaries

Wrap components with <Suspense> boundaries to enable streaming. React will send the HTML for the loading fallback first, and then send the remaining HTML along with an inline <script> tag that replaces the loading fallback once the content finishes loading. This allows users to see content progressively.

renderToPipeableStream signature and return value

renderToPipeableStream renders a React tree to a pipeable Node.js Stream. The signature is: const { pipe, abort } = renderToPipeableStream(reactNode, options?). It returns an object with two methods: pipe, which outputs HTML into a provided Writable Node.js Stream, and abort, which lets you abort server rendering and render the rest on the client.

renderToPipeableStream is Node.js specific

renderToPipeableStream is specific to Node.js environments. Environments with Web Streams, like Deno and modern edge runtimes, should use renderToReadableStream instead.

renderToPipeableStream reactNode parameter

The reactNode parameter is a React node you want to render to HTML, such as a JSX element like <App />. It is expected to represent the entire document, so the App component should render the <html> tag.

renderToPipeableStream options: onAllReady

onAllReady is an optional callback that fires when all rendering is complete, including both the shell and all additional content. You can use this instead of onShellReady for crawlers and static generation. If you start streaming here, you won't get any progressive loading and the stream will contain the final HTML.

renderToPipeableStream options: onShellReady

onShellReady is an optional callback that fires right after the initial shell has been rendered. You can set the status code and call pipe here to start streaming. React will stream the additional content after the shell along with the inline <script> tags that replace the HTML loading fallbacks with the content.

renderToPipeableStream options: onShellError

onShellError is an optional callback that fires if there was an error rendering the initial shell. It receives the error as an argument. No bytes were emitted from the stream yet, and neither onShellReady nor onAllReady will get called, so you can output a fallback HTML shell.

renderToPipeableStream options: progressiveChunkSize

progressiveChunkSize is an optional number specifying the number of bytes in a chunk. This follows a default heuristic for determining chunk sizes.

renderToPipeableStream example with bootstrapScripts

import { renderToPipeableStream } from 'react-dom/server'; app.use('/', (request, response) => { const { pipe } = renderToPipeableStream(<App />, { bootstrapScripts: ['/main.js'], onShellReady() { response.setHeader('content-type', 'text/html'); pipe(response); } }); });

Server-rendered HTML structure with doctype and scripts

React will inject the doctype and bootstrap <script> tags into the resulting HTML stream. The output will be: <!DOCTYPE html><html><!-- ... HTML from your components ... --></html><script src="/main.js" async=""></script>

Asset map pattern for hashed asset URLs

To handle hashed asset filenames from the build process, your root component can read the real filenames from a map passed as a prop. Pass the assetMap from the server to the component, and serialize it via bootstrapScriptContent so the client can access it via window.assetMap. Both client and server must render App with the same assetMap prop to avoid hydration errors.

Nested Suspense boundaries for granular streaming

You can nest <Suspense> boundaries to create a more granular loading sequence. Only components not wrapped in any <Suspense> boundary must finish rendering first. Components inside nested boundaries will stream their loading fallbacks and content as they load.

Streaming does not wait for React or JavaScript to load

HTML content from the server will get progressively revealed before any of the <script> tags load. This means users can see content before React itself loads in the browser or the app becomes interactive.

Shell definition in server rendering

The shell is the part of your app outside of any <Suspense> boundaries. It determines the earliest loading state that the user may see. The shell should feel minimal but complete, like a skeleton of the entire page layout.

onShellReady callback timing

The onShellReady callback fires when the entire shell has been rendered. By the time onShellReady fires, components in nested <Suspense> boundaries might still be loading data. Usually, you'll start streaming then by calling pipe.

Error logging pattern with custom onError

To log crash reports, override the onError callback to call both console.error and your logging function. Example: onError(error) { console.error(error); logServerCrashReport(error); }

onShellError fallback HTML pattern

If an error occurs while rendering the shell, override onShellError to send a fallback HTML. At this point no bytes were emitted from the stream yet. Example: onShellError(error) { response.statusCode = 500; response.setHeader('content-type', 'text/html'); response.send('<h1>Something went wrong</h1>'); }

Error recovery outside the shell

If an error happens in a component wrapped in <Suspense> (outside the shell), React will emit the loading fallback into the HTML, give up on server rendering that content, and retry rendering it on the client. If client retry also fails, React throws the error on the client. The onError and client onRecoverableError callbacks will fire.

Status code tradeoff with streaming

Once you start streaming, you can no longer set the response status code. Use the shell to solve this: if the shell errors, use onShellError to set an error status code. Otherwise, send OK status in onShellReady.

Track errors outside shell for status code

You can use a flag like didError that gets set in onError to track whether any error occurred outside the shell. Then in onShellReady, set response.statusCode = didError ? 500 : 200. This only catches errors that happened while generating the initial shell content.

renderToReadableStream signature and return type

renderToReadableStream has the signature: const stream = await renderToReadableStream(reactNode, options?). It returns a Promise that resolves to a Readable Web Stream if rendering the shell is successful, or rejects if rendering the shell fails. The returned stream has an additional property allReady, a Promise that resolves when all rendering is complete, including both the shell and all additional content.

renderToReadableStream parameters: reactNode and options

renderToReadableStream takes two parameters: (1) reactNode - a React node to render to HTML, expected to represent the entire document including the <html> tag; (2) options - an optional object with streaming options.

renderToReadableStream options: bootstrapScriptContent

bootstrapScriptContent is an optional string option for renderToReadableStream that, if specified, will be placed in an inline <script> tag.

renderToReadableStream options: bootstrapScripts

bootstrapScripts is an optional array of string URLs for <script> tags to emit on the page. Use this to include the <script> that calls hydrateRoot. Omit it if you don't want to run React on the client at all.

renderToReadableStream options: bootstrapModules

bootstrapModules is an optional option for renderToReadableStream, similar to bootstrapScripts, but emits <script type="module"> tags instead.

renderToReadableStream options: formState

formState is an optional option for renderToReadableStream containing the form state from a form submission handled by a Server Function. If the page is rendered in response to a submission of a form that uses useActionState with a permalink, pass the resulting form state so that React embeds it into the HTML for hydration. The same value must be passed to hydrateRoot on the client.

renderToReadableStream options: identifierPrefix

identifierPrefix is an optional string option for renderToReadableStream that React uses for IDs generated by useId. Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to hydrateRoot.

renderToReadableStream options: importMap

importMap is an optional object option for renderToReadableStream with imports and scopes properties. React emits it as an inline <script type="importmap"> tag before any module scripts, so that <script type="module"> tags can use bare module specifiers. When nonce is set, it is also applied to the import map script.

renderToReadableStream options: maxHeadersLength

maxHeadersLength is an optional number option for renderToReadableStream specifying the maximum total length of the header content passed to onHeaders, measured in UTF-16 code units. Defaults to 2000. Once the limit is reached, React stops adding resource hints to the headers.

renderToReadableStream options: namespaceURI

namespaceURI is an optional string option for renderToReadableStream with the root namespace URI for the stream. Defaults to regular HTML. Pass 'http://www.w3.org/2000/svg' for SVG or 'http://www.w3.org/1998/Math/MathML' for MathML.

renderToReadableStream options: nonce

nonce is an optional string option for renderToReadableStream containing a nonce value to allow scripts for script-src Content-Security-Policy. To use different nonces for scripts and styles, pass an object with script and style properties instead.

renderToReadableStream options: onBrowserBailout

onBrowserBailout is an optional callback option for renderToReadableStream that React calls when it recovers from browser() by leaving a Suspense fallback for the browser to replace. It receives an Error describing the browser-only render and an errorInfo object containing the componentStack. If a reason was passed to browser, it is available as error.cause. By default, React does nothing.

renderToReadableStream options: onError

onError is an optional callback option for renderToReadableStream that fires whenever there is a server error, whether recoverable or not. By default, this only calls console.error. If you override it to log crash reports, make sure that you still call console.error. You can also use it to adjust the status code before the shell is emitted.

renderToReadableStream options: onHeaders

onHeaders is an optional callback option for renderToReadableStream that fires when React has determined the resource hints for the document, such as preconnects and stylesheet, font, or high-priority image preloads. It receives a Headers instance containing the corresponding Link header value, so you can send it as an HTTP response header or as a 103 Early Hints response. React calls it even when there are no resource hints to send. The header content is capped by maxHeadersLength.

renderToReadableStream options: progressiveChunkSize

progressiveChunkSize is an optional number option for renderToReadableStream specifying the number of bytes in a chunk. The default heuristic can be read about in the React source code.

renderToReadableStream options: signal

signal is an optional AbortSignal option for renderToReadableStream that lets you abort server rendering and render the rest on the client.

renderToReadableStream basic usage example

import { renderToReadableStream } from 'react-dom/server'; async function handler(request) { const stream = await renderToReadableStream(<App />, { bootstrapScripts: ['/main.js'] }); return new Response(stream, { headers: { 'content-type': 'text/html' }, }); }

Give your agent this brain