How to Upgrade Your Server‑Side Rendering to React 18: New APIs & Best Practices
This guide explains how to migrate a React server‑side rendering setup to React 18 by installing the latest version, replacing renderToString with pipeToNodeWritable, and adopting the new API surface while handling Suspense and streaming nuances.
本文源于翻译 Upgrading to React 18 on the server
Overview
Steps to upgrade the server to React 18:
Install the latest React 18 version.
Replace
renderToStringwith
pipeToNodeWritableto unlock new features.
React 18 improves the SSR architecture for better performance, making these changes very useful.
API Changes
Historically, React did not support Suspense on the server. React 18 changes this, offering different APIs for varying levels of Suspense support:
renderToString: works with limited Suspense support.
renderToNodeStream: not recommended; fully supports Suspense but not streaming.
pipeToNodeWritable: recommended ; fully supports both Suspense and streaming.
Existing API
renderToString(React.Node): stringThis API can still be used, but it lacks the new capabilities, so we recommend switching to
pipeToNodeWritable. Since it is not deprecated,
renderToStringcan still be used.
In React 18,
renderToStringonly offers very limited support for
<Suspense>. Previously, using
<Suspense>would throw an error. Starting with React 18, Suspense boundaries are marked as “client‑rendered” and immediately render the HTML inside the fallback. After the client loads JavaScript, the content is re‑rendered. Using a top‑level
<Suspense>that suspends during rendering can cause the server‑rendered app to exit.
This change does not affect existing applications because Suspense never worked on the server before. However, conditionally rendering
<Suspense>on the client may cause mismatched content to be removed from the DOM, which React does not support.
Note: This behavior is not very useful, but it is the best we can do because
renderToStringis synchronous and cannot “await” anything. That is why we recommend using the new
pipeToNodeWritable.
Deprecated API
renderToNodeStream(React.Node): ReadableIn React 18, using
renderToNodeStreamis fully discouraged and will emit warnings. It was the first streaming API but its functionality is limited (it cannot wait for data). It buffers the entire content until the stream ends, so it no longer performs true streaming, making its use confusing.
We are replacing it with
pipeToNodeWritable.
Recommended API
pipeToNodeWritable(React.Node, Writable, Options): ControlsThis is the API we recommend moving forward; it supports all new features:
Fully built‑in support (integrated data fetching).
Use
lazyfor code‑splitting without flash‑of‑content issues.
Delayed content in the HTML stream appears later.
In the latest Alpha version, you can use it like this:
<code>import { pipeToNodeWritable } from 'react-dom/server';
</code>This API is not yet integrated with data fetching. Common Suspense mechanisms work, but we have no guidance yet on pre‑populating client caches from server data.
Open questions remain, such as handling the
<title>tag because the stream may start before an “ideal” title is available. Developers are encouraged to experiment with solutions.
Other APIs
There are a few related APIs for generating static markup:
renderToStaticMarkup: still usable (limited Suspense support).
renderToStaticNodeStream: not recommended (full Suspense support, no streaming).
These have not yet received the new recommended API equivalents for
pipeToNodeWritable.
KooFE Frontend Team
Follow the latest frontend updates
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.