From a78cc996186f46f0bb479957791bb61e8c9cb4c3 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 7 Apr 2022 00:59:23 +0100 Subject: [PATCH] Edits for ReactDOMServer API (#4558) * Edits for ReactDOMServer API * Move note below example * No destructure * Rm hr * Add onError * Drop SEO * Update reference-react-dom-server.md --- content/docs/reference-react-dom-server.md | 152 +++++++++++++-------- 1 file changed, 97 insertions(+), 55 deletions(-) diff --git a/content/docs/reference-react-dom-server.md b/content/docs/reference-react-dom-server.md index 7a22f1e1b..e5ed63138 100644 --- a/content/docs/reference-react-dom-server.md +++ b/content/docs/reference-react-dom-server.md @@ -10,101 +10,98 @@ The `ReactDOMServer` object enables you to render components to static markup. T ```js // ES modules -import ReactDOMServer from 'react-dom/server'; +import * as ReactDOMServer from 'react-dom/server'; // CommonJS var ReactDOMServer = require('react-dom/server'); ``` ## Overview {#overview} -The following methods can be used in both the server and browser environments: +These methods are only available in the **environments with [Node.js Streams](https://nodejs.dev/learn/nodejs-streams):** + +- [`renderToPipeableStream()`](#rendertopipeablestream) +- [`renderToNodeStream()`](#rendertonodestream) (Deprecated) +- [`renderToStaticNodeStream()`](#rendertostaticnodestream) + +These methods are only available in the **environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)** (this includes browsers, Deno, and some modern edge runtimes): + +- [`renderToReadableStream()`](#rendertoreadablestream) + +The following methods can be used in both the server and Web API environments: - [`renderToString()`](#rendertostring) - [`renderToStaticMarkup()`](#rendertostaticmarkup) -These additional methods depend on a package (`stream`) that is **only available on the server**, and won't work in the browser. - -- [`renderToPipeableStream()`](#rendertopipeablestream) -- [`renderToReadableStream()`](#rendertoreadablestream) -- [`renderToNodeStream()`](#rendertonodestream) (Deprecated) -- [`renderToStaticNodeStream()`](#rendertostaticnodestream) - -* * * - ## Reference {#reference} -### `renderToString()` {#rendertostring} - -```javascript -ReactDOMServer.renderToString(element) -``` - -Render a React element to its initial HTML. React will return an HTML string. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes. - -If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience. - -* * * - -### `renderToStaticMarkup()` {#rendertostaticmarkup} - -```javascript -ReactDOMServer.renderToStaticMarkup(element) -``` - -Similar to [`renderToString`](#rendertostring), except this doesn't create extra DOM attributes that React uses internally, such as `data-reactroot`. This is useful if you want to use React as a simple static page generator, as stripping away the extra attributes can save some bytes. - -If you plan to use React on the client to make the markup interactive, do not use this method. Instead, use [`renderToString`](#rendertostring) on the server and [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on the client. - -* * * - ### `renderToPipeableStream()` {#rendertopipeablestream} ```javascript ReactDOMServer.renderToPipeableStream(element, options) ``` -Render a React element to its initial HTML. Returns a [Control object](https://github.com/facebook/react/blob/3f8990898309c61c817fbf663f5221d9a00d0eaa/packages/react-dom/src/server/ReactDOMFizzServerNode.js#L49-L54) that allows you to pipe the output or abort the request. Fully supports Suspense and streaming of HTML with "delayed" content blocks "popping in" later through javascript execution. [Read more](https://github.com/reactwg/react-18/discussions/37) +Render a React element to its initial HTML. Returns a stream with a `pipe(res)` method to pipe the output and `abort()` to abort the request. Fully supports Suspense and streaming of HTML with "delayed" content blocks "popping in" via inline `' ); - } + }, + onAllReady() { + // If you don't want streaming, use this instead of onShellReady. + // This will fire after the entire page content is ready. + // You can use this for crawlers or static generation. + + // res.statusCode = didError ? 500 : 200; + // res.setHeader('Content-type', 'text/html'); + // stream.pipe(res); + }, + onError(err) { + didError = true; + console.error(err); + }, } ); ``` +See the [full list of options](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-dom/src/server/ReactDOMFizzServerNode.js#L36-L46). + +> Note: +> +> This is a Node.js-specific API. Environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), like Deno and modern edge runtimes, should use [`renderToReadableStream`](#rendertoreadablestream) instead. +> + * * * ### `renderToReadableStream()` {#rendertoreadablestream} ```javascript - ReactDOMServer.renderToReadableStream(element, options); +ReactDOMServer.renderToReadableStream(element, options); ``` -Streams a React element to its initial HTML. Returns a [Readable Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream). Fully supports Suspense and streaming of HTML. [Read more](https://github.com/reactwg/react-18/discussions/127) +Streams a React element to its initial HTML. Returns a Promise that resolves to a [Readable Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream). Fully supports Suspense and streaming of HTML. [Read more](https://github.com/reactwg/react-18/discussions/127) If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience. -``` +```javascript let controller = new AbortController(); +let didError = false; try { let stream = await renderToReadableStream( @@ -112,14 +109,21 @@ try { , { signal: controller.signal, + onError(e) { + didError = true; + console.error(err); + } } ); - // This is to wait for all suspense boundaries to be ready. You can uncomment - // this line if you don't want to stream to the client + // This is to wait for all Suspense boundaries to be ready. You can uncomment + // this line if you want to buffer the entire HTML instead of streaming it. + // You can use this for crawlers or static generation: + // await stream.allReady; return new Response(stream, { + status: didError ? 500 : 200, headers: {'Content-Type': 'text/html'}, }); } catch (error) { @@ -132,15 +136,23 @@ try { ); } ``` + +See the [full list of options](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js#L27-L35). + +> Note: +> +> This API depends on [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API). For Node.js, use [`renderToPipeableStream`](#rendertopipeablestream) instead. +> + * * * -### `renderToNodeStream()` {#rendertonodestream} (Deprecated) +### `renderToNodeStream()` (Deprecated) {#rendertonodestream} ```javascript ReactDOMServer.renderToNodeStream(element) ``` -Render a React element to its initial HTML. Returns a [Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) that outputs an HTML string. The HTML output by this stream is exactly equal to what [`ReactDOMServer.renderToString`](#rendertostring) would return. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes. +Render a React element to its initial HTML. Returns a [Node.js Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) that outputs an HTML string. The HTML output by this stream is exactly equal to what [`ReactDOMServer.renderToString`](#rendertostring) would return. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes. If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience. @@ -169,3 +181,33 @@ If you plan to use React on the client to make the markup interactive, do not us > Server-only. This API is not available in the browser. > > The stream returned from this method will return a byte stream encoded in utf-8. If you need a stream in another encoding, take a look at a project like [iconv-lite](https://www.npmjs.com/package/iconv-lite), which provides transform streams for transcoding text. + +* * * + +### `renderToString()` {#rendertostring} + +```javascript +ReactDOMServer.renderToString(element) +``` + +Render a React element to its initial HTML. React will return an HTML string. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes. + +If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience. + +> Note +> +> This API has limited Suspense support and does not support streaming. +> +> On the sever, it is recommended to use either [`renderToPipeableStream`](#rendertopipeablestream) (for Node.js) or [`renderToReadableStream`](#rendertoreadablestream) (for Web Streams) instead. + +* * * + +### `renderToStaticMarkup()` {#rendertostaticmarkup} + +```javascript +ReactDOMServer.renderToStaticMarkup(element) +``` + +Similar to [`renderToString`](#rendertostring), except this doesn't create extra DOM attributes that React uses internally, such as `data-reactroot`. This is useful if you want to use React as a simple static page generator, as stripping away the extra attributes can save some bytes. + +If you plan to use React on the client to make the markup interactive, do not use this method. Instead, use [`renderToString`](#rendertostring) on the server and [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on the client.