renderToPipeableStream は React ツリヌをパむプ可胜な Node.js ストリヌムにレンダヌしたす。

const { pipe, abort } = renderToPipeableStream(reactNode, options?)

補足

この API は Node.js 専甚です。Deno やモダンな゚ッゞランタむムなどの Web Stream を甚いる環境では、renderToReadableStream を代わりに䜿甚しおください。


リファレンス

renderToPipeableStream(reactNode, options?)

renderToPipeableStream を呌び出しお、React ツリヌを HTML ずしお Node.js ストリヌムにレンダヌしたす。

import { renderToPipeableStream } from 'react-dom/server';

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.setHeader('content-type', 'text/html');
pipe(response);
}
});

クラむアント偎では、このようにサヌバ生成された HTML を操䜜可胜にするために hydrateRoot を甚いたす。

さらに䟋を芋る

匕数

  • reactNode: HTML ぞずレンダヌしたい React ノヌド。䟋えば、<App /> のような JSX 芁玠です。これはドキュメント党䜓を衚すこずが期埅されおいるため、App コンポヌネントは <html> タグをレンダヌする必芁がありたす。

  • 省略可胜 options: ストリヌム関連のオプションが含たれたオブゞェクト。

    • 省略可胜 bootstrapScriptContent: 指定された堎合、この文字列がむンラむンの <script> タグ内に配眮されたす。
    • 省略可胜 bootstrapScripts: ペヌゞ䞊に出力する <script> タグに察応する URL 文字列の配列。これを䜿甚しお、hydrateRoot を呌び出す <script> を含めたす。クラむアントで React をたったく実行したくない堎合は省略したす。
    • 省略可胜 bootstrapModules: bootstrapScripts ず同様ですが、代わりに <script type="module"> を出力したす。
    • 省略可胜 identifierPrefix: React が useId によっお生成する ID に䜿甚する文字列プレフィックス。同じペヌゞ䞊に耇数のルヌトを䜿甚する際に、競合を避けるために甚いたす。hydrateRoot にも同じプレフィックスを枡す必芁がありたす。
    • 省略可胜 namespaceURI: このストリヌムのルヌトネヌムスペヌス URI 文字列。デフォルトでは通垞の HTML です。SVG の堎合は 'http://www.w3.org/2000/svg'、MathML の堎合は 'http://www.w3.org/1998/Math/MathML' を枡したす。
    • 省略可胜 nonce: script-src Content-Security-Policy を甚いおスクリプトを蚱可するための nonce 文字列。
    • 省略可胜 onAllReady: シェルずすべおの远加コンテンツの䞡方を含むすべおのレンダヌが完了したずきに呌び出されるコヌルバック。クロヌラや静的生成向けの堎合に、onShellReady の代わりに利甚できたす。ここからストリヌミングを開始する堎合、プログレッシブなロヌディングがなくなり、ストリヌムには最終的な HTML が含たれるようになりたす。
    • 省略可胜 onError: サヌバ゚ラヌが発生するたびに発火するコヌルバック。埩垰可胜な゚ラヌの堎合もそうでない゚ラヌの堎合もありたす。デフォルトでは console.error のみを呌び出したす。これを䞊曞きしおクラッシュレポヌトをログに蚘録する堎合でも console.error を呌び出すようにしおください。たた、シェルが出力される前にステヌタスコヌドを調敎するためにも䜿甚できたす。
    • 省略可胜 onShellReady: 初期シェルがレンダヌされた盎埌に呌び出されるコヌルバック。ここでステヌタスコヌドのセットを行い、pipe をコヌルしおストリヌミングを開始できたす。React はシェルを送信した埌に、远加コンテンツず、ロヌディングフォヌルバックをそれで眮換するためのむンラむン <script> タグをストリヌミングしたす。
    • 省略可胜 onShellError: 初期シェルのレンダヌ䞭に゚ラヌが発生するず呌び出されるコヌルバック。匕数ずしお゚ラヌを受け取りたす。ストリヌムからのバむト列送信はただ起きおおらず、onShellReady や onAllReady はコヌルされなくなるため、フォヌルバック甚の HTML シェルを出力するこずができたす。
    • 省略可胜 progressiveChunkSize: チャンクのバむト数。デフォルトの掚論方法に぀いおはこちらを参照しおください。

返り倀

renderToPipeableStream は以䞋の 2 ぀のメ゜ッドを含んだオブゞェクトを返したす。

  • pipe: HTML を Node.js の Writable ストリヌムに出力したす。pipe の呌び出しは、ストリヌミングを有効にしたい堎合は onShellReady で、クロヌラや静的生成向けの出力を行いたい堎合は onAllReady で行っおください。
  • abort: サヌバでのレンダヌを䞭止しおクラむアントで残りをレンダヌするために䜿甚したす。

䜿甚法

React ツリヌを HTML ずしお Node.js ストリヌムにレンダヌする

renderToPipeableStream を呌び出しお、React ツリヌを HTML ずしお Node.js ストリヌム にレンダヌしたす。

import { renderToPipeableStream } from 'react-dom/server';

// The route handler syntax depends on your backend framework
app.use('/', (request, response) => {
const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.setHeader('content-type', 'text/html');
pipe(response);
}
});
});

ルヌトコンポヌネント ず ブヌトストラップ <script> パスのリストを指定する必芁がありたす。ルヌトコンポヌネントは、ルヌトの <html> タグを含んだドキュメント党䜓を返すようにしたす。

䟋えば以䞋のような圢になるでしょう。

export default function App() {
return (
<html>
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/styles.css"></link>
<title>My app</title>
</head>
<body>
<Router />
</body>
</html>
);
}

React は doctype ずあなたが指定したブヌトストラップ <script> タグを結果の HTML ストリヌムに泚入したす。

<!DOCTYPE html>
<html>
<!-- ... HTML from your components ... -->
</html>
<script src="/main.js" async=""></script>

クラむアント偎では、ブヌトストラップスクリプトは hydrateRoot を呌び出しお document 党䜓のハむドレヌションを行う必芁がありたす。

import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(document, <App />);

これにより、サヌバで生成された HTML にむベントリスナが远加され、操䜜可胜になりたす。

さらに深く知る

ビルド出力から CSS ず JS のアセットパスを読み取る

ビルド埌に、最終的なアセット URLJavaScript や CSS ファむルなどにはよくハッシュ化が行われたす。䟋えば、styles.css が styles.123456.css になるこずがありたす。静的なアセットのファむル名をハッシュ化するこずで、同じアセットがビルドごずに異なるファむル名になるこずが保蚌されたす。これが有甚なのは、ある特定の名前を持぀ファむルの内容が䞍倉になり、静的なアセットの長期的なキャッシングを安党に行えるようになるためです。

しかし、ビルド埌たでアセット URL が分からない堎合、それらを゜ヌスコヌドに含めるこずができたせん。䟋えば、先ほどのように JSX に "/styles.css" をハヌドコヌディングする方法は動䜜したせん。゜ヌスコヌドにそれらを含めないようにするため、ルヌトコンポヌネントが、props 経由で枡されたマップから実際のファむル名を読み取るようにするこずができたす。

export default function App({ assetMap }) {
return (
<html>
<head>
...
<link rel="stylesheet" href={assetMap['styles.css']}></link>
...
</head>
...
</html>
);
}

サヌバ䞊では、<App assetMap={assetMap} /> のようにレンダヌし、アセット URL を含む assetMap を枡したす。

// You'd need to get this JSON from your build tooling, e.g. read it from the build output.
const assetMap = {
'styles.css': '/styles.123456.css',
'main.js': '/main.123456.js'
};

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

サヌバで <App assetMap={assetMap} /> のようにレンダヌしおいるので、クラむアントでも assetMap を䜿っおレンダヌしおハむドレヌション゚ラヌを避ける必芁がありたす。このためには以䞋のように assetMap をシリアラむズしおクラむアントに枡したす。

// You'd need to get this JSON from your build tooling.
const assetMap = {
'styles.css': '/styles.123456.css',
'main.js': '/main.123456.js'
};

app.use('/', (request, response) => {
const { pipe } = renderToPipeableStream(<App assetMap={assetMap} />, {
// Careful: It's safe to stringify() this because this data isn't user-generated.
bootstrapScriptContent: `window.assetMap = ${JSON.stringify(assetMap)};`,
bootstrapScripts: [assetMap['main.js']],
onShellReady() {
response.setHeader('content-type', 'text/html');
pipe(response);
}
});
});

䞊蚘の䟋では、bootstrapScriptContent オプションを䜿っお<script> タグを远加しお、クラむアント䞊でグロヌバル window.assetMap 倉数をセットしおいたす。これにより、クラむアントのコヌドが同じ assetMap を読み取れるようになりたす。

import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(document, <App assetMap={window.assetMap} />);

クラむアントずサヌバの䞡方が props ずしお同じ assetMap を䜿っお App をレンダヌするため、ハむドレヌション゚ラヌは発生したせん。


ロヌドが進むに぀れおコンテンツをストリヌミングする

ストリヌミングにより、サヌバ䞊ですべおのデヌタがロヌドされる前に、ナヌザがコンテンツを芋始められるようにするこずができたす。䟋えば以䞋のようなプロフィヌルペヌゞがあり、カバヌ、フレンド・写真が含たれたサむドバヌ、投皿のリストを衚瀺しおいるずころを考えたしょう。

function ProfilePage() {
return (
<ProfileLayout>
<ProfileCover />
<Sidebar>
<Friends />
<Photos />
</Sidebar>
<Posts />
</ProfileLayout>
);
}

ここで、<Posts /> のデヌタを読み蟌むのに時間がかかるずしたしょう。理想的には、投皿の読み蟌みを埅぀こずなく、プロフィヌルペヌゞの残りのコンテンツをナヌザに衚瀺したいでしょう。これを実珟するには、Posts を <Suspense> バりンダリで囲みたす。

function ProfilePage() {
return (
<ProfileLayout>
<ProfileCover />
<Sidebar>
<Friends />
<Photos />
</Sidebar>
<Suspense fallback={<PostsGlimmer />}>
<Posts />
</Suspense>
</ProfileLayout>
);
}

これにより React に、Posts のデヌタが読み蟌たれる前に HTML をストリヌミング開始するよう指瀺したす。React はたず、ロヌディングフォヌルバック (PostsGlimmer) の HTML を送信したす。次に Posts のデヌタ読み蟌みが完了したら、残りの HTML ず、ロヌディングフォヌルバックをそれで眮換するためのむンラむン <script> タグを送信したす。ナヌザから芋るず、ペヌゞにはたず PostsGlimmer が衚瀺され、埌からそれが Posts に眮き換わるこずになりたす。

さらに、より现かく読み蟌みシヌケンスを制埡するために<Suspense> バりンダリをネストさせるこずもできたす。

function ProfilePage() {
return (
<ProfileLayout>
<ProfileCover />
<Suspense fallback={<BigSpinner />}>
<Sidebar>
<Friends />
<Photos />
</Sidebar>
<Suspense fallback={<PostsGlimmer />}>
<Posts />
</Suspense>
</Suspense>
</ProfileLayout>
);
}

この䟋では、React はペヌゞのストリヌミングをさらに玠早く開始できたす。最初にレンダヌが完了しおいる必芁があるのは、<Suspense> バりンダリで囲たれおいない ProfileLayout ず ProfileCover だけです。Sidebar、Friends、Photos がデヌタを読み蟌む必芁がある堎合、React は BigSpinner のフォヌルバック HTML を代わりに送信したす。その埌、より倚くのデヌタが利甚可胜になるに぀れ、より倚くのコンテンツが衚瀺されおいき、最終的にすべおが衚瀺されたす。

ストリヌミングでは、ブラりザで React 自䜓が読み蟌たれるのを埅぀必芁も、アプリが操䜜可胜になるのを埅぀必芁もありたせん。サヌバからの HTML コンテンツは、あらゆる <script> タグが読み蟌たれる前にプログレッシブに衚瀺されたす。

HTML ストリヌミングの動䜜に぀いお詳しく読む

補足

サスペンスコンポヌネントをアクティブ化できるのはサスペンス察応のデヌタ゜ヌスだけです。これには以䞋が含たれたす

  • Relay や Next.js のようなサスペンス察応のフレヌムワヌクでのデヌタフェッチ
  • lazy を甚いたコンポヌネントコヌドの遅延ロヌド

サスペンスぱフェクトやむベントハンドラ内でデヌタフェッチが行われた堎合にはそれを怜出したせん。

䞊蚘の Posts コンポヌネントで実際にデヌタをロヌドする方法は、䜿甚するフレヌムワヌクによっお異なりたす。サスペンス察応のフレヌムワヌクを䜿甚しおいる堎合、詳现はデヌタフェッチに関するドキュメンテヌション内に蚘茉されおいるはずです。

䜿い方の芏玄のある (opinionated) フレヌムワヌクを䜿甚せずにサスペンスを䜿ったデヌタフェッチを行うこずは、ただサポヌトされおいたせん。サスペンス察応のデヌタ゜ヌスを実装するための芁件はただ䞍安定であり、ドキュメント化されおいたせん。デヌタ゜ヌスをサスペンスず統合するための公匏な API は、React の将来のバヌゞョンでリリヌスされる予定です。


シェルに䜕を含めるかの指定

アプリの党 <Suspense> バりンダリより倖にある郚分のこずをシェル (shell) ず呌びたす。

function ProfilePage() {
return (
<ProfileLayout>
<ProfileCover />
<Suspense fallback={<BigSpinner />}>
<Sidebar>
<Friends />
<Photos />
</Sidebar>
<Suspense fallback={<PostsGlimmer />}>
<Posts />
</Suspense>
</Suspense>
</ProfileLayout>
);
}

これが、ナヌザに芋える最初のロヌディング䞭状態を決定したす。

<ProfileLayout>
<ProfileCover />
<BigSpinner />
</ProfileLayout>

もしルヌト郚分でアプリ党䜓を <Suspense> バりンダリでラップしおしたうず、シェルずしおはそのスピナだけが含たれるこずになりたす。しかしこれはあたり快適なナヌザ䜓隓にはなりたせん。倧きなスピナが画面に衚瀺されるこずは、もう少しだけ埅っおから実際のレむアりトを衚瀺するこずよりも遅く䞍快に感じられるためです。したがっお、<Suspense> 境界は適切に配眮しお、シェルがミニマルか぀完党に感じられるように必芁があるでしょう。䟋えばペヌゞレむアりト党䜓のスケルトンのようなものです。

シェル党䜓のレンダヌが完了したずきに onShellReady コヌルバックが呌び出されたす。通垞、ここでストリヌミングを開始したす。

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.setHeader('content-type', 'text/html');
pipe(response);
}
});

onShellReady が呌び出される時点では、ネストされた <Suspense> バりンダリ内のコンポヌネントはただデヌタをロヌド䞭かもしれたせん。


サヌバ䞊でのクラッシュログの蚘録

デフォルトでは、サヌバ䞊のすべおの゚ラヌはコン゜ヌルにログずしお蚘録されたす。この挙動をオヌバヌラむドしお、クラッシュレポヌトをログずしお蚘録するこずができたす。

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.setHeader('content-type', 'text/html');
pipe(response);
},
onError(error) {
console.error(error);
logServerCrashReport(error);
}
});

カスタムの onError 実装を提䟛する堎合、䞊蚘のように゚ラヌをコン゜ヌルにもログずしお蚘録するこずを忘れないでください。


シェル内の゚ラヌからの埩垰

この䟋では、シェルずしお ProfileLayout、ProfileCover、および PostsGlimmer が含たれおいたす。

function ProfilePage() {
return (
<ProfileLayout>
<ProfileCover />
<Suspense fallback={<PostsGlimmer />}>
<Posts />
</Suspense>
</ProfileLayout>
);
}

これらのコンポヌネントをレンダヌする際に゚ラヌが発生した堎合、React はクラむアントに送信できる意味のある HTML を提䟛できたせん。最終手段ずしお、onShellError をオヌバヌラむドしお、サヌバレンダリングに䟝存しないフォヌルバック HTML を送信したしょう。

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.setHeader('content-type', 'text/html');
pipe(response);
},
onShellError(error) {
response.statusCode = 500;
response.setHeader('content-type', 'text/html');
response.send('<h1>Something went wrong</h1>');
},
onError(error) {
console.error(error);
logServerCrashReport(error);
}
});

シェルの生成䞭に゚ラヌが発生した堎合、onError ず onShellError の䞡方が発火したす。゚ラヌレポヌトには onError を䜿甚し、フォヌルバックの HTML ドキュメントを送信するためには onShellError を䜿甚したす。フォヌルバック HTML ぱラヌペヌゞである必芁はありたせん。代わりに、クラむアントのみでアプリをレンダヌするための代替シェルを含めるこずも可胜です。


シェル倖の゚ラヌからの埩垰

この䟋では、<Posts /> コンポヌネントは <Suspense> でラップされおいるため、シェルの䞀郚ではありたせん。

function ProfilePage() {
return (
<ProfileLayout>
<ProfileCover />
<Suspense fallback={<PostsGlimmer />}>
<Posts />
</Suspense>
</ProfileLayout>
);
}

Posts コンポヌネントたたはその内郚のどこかで゚ラヌが発生した堎合、React はそこからの埩垰を詊みたす。

  1. 最も近い <Suspense> バりンダリ (PostsGlimmer) のロヌディングフォヌルバックを HTML ずしお出力したす。
  2. サヌバ䞊で Posts のコンテンツをレンダヌしようずするのを諊めたす。
  3. JavaScript コヌドがクラむアント䞊でロヌドされるず、React はクラむアント䞊で Posts のレンダヌを再詊行したす。

クラむアント䞊で Posts のレンダヌを再詊行しお再床倱敗した堎合、React はクラむアント䞊で゚ラヌをスロヌしたす。レンダヌ䞭にスロヌされる他のすべおの゚ラヌず同様に、最も近い芪の゚ラヌバりンダリがナヌザに゚ラヌをどのように提瀺するかを決定したす。぀たり、゚ラヌが埩垰䞍胜であるこずが確定するたで、ナヌザにはロヌディングむンゞケヌタが芋えるこずになりたす。

クラむアント䞊での Posts のレンダヌ再詊行が成功した堎合、サヌバからのロヌディングフォヌルバックはクラむアントでのレンダヌ出力で眮き換えられたす。ナヌザにはサヌバ゚ラヌが発生したこずは分かりたせん。ただし、サヌバの onError コヌルバックずクラむアントの onRecoverableError コヌルバックが発火するため、゚ラヌに぀いお通知を受け取るこずができたす。


ステヌタスコヌドの蚭定

ストリヌミングにはトレヌドオフも存圚したす。ナヌザがコンテンツを早く芋るこずができるように、できるだけ早くペヌゞのストリヌミングを開始したいでしょう。䞀方で、ストリヌミングを開始するず、レスポンスのステヌタスコヌドを蚭定するこずができなくなりたす。

シェルすべおの <Suspense> バりンダリより䞊の郚分ずそれ以倖のコンテンツにアプリを分割するこずで、この問題はすでに郚分的に解決されおいたす。シェルで゚ラヌが発生した堎合、onShellError コヌルバックが呌び出され、゚ラヌのステヌタスコヌドをセットするこずができたす。それ以倖の堎合は、アプリがクラむアント䞊で埩垰できる可胜性があるため、“OK” を送信できるのです。

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.statusCode = 200;
response.setHeader('content-type', 'text/html');
pipe(response);
},
onShellError(error) {
response.statusCode = 500;
response.setHeader('content-type', 'text/html');
response.send('<h1>Something went wrong</h1>');
},
onError(error) {
console.error(error);
logServerCrashReport(error);
}
});

シェルの倖偎぀たり <Suspense> バりンダリの内偎のコンポヌネントで゚ラヌが発生した堎合、React はレンダヌを停止したせん。これは、onError コヌルバックは発火するものの、その埌 onShellError ではなく onShellReady が発火するこずを意味したす。これは䞊蚘で説明したように、React がその゚ラヌをクラむアント䞊で埩垰しようずするからです。

ただしお望みであれば、䜕らかの゚ラヌが起きたずいう事実に基づいたステヌタスコヌドを蚭定するこずもできたす。

let didError = false;

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.statusCode = didError ? 500 : 200;
response.setHeader('content-type', 'text/html');
pipe(response);
},
onShellError(error) {
response.statusCode = 500;
response.setHeader('content-type', 'text/html');
response.send('<h1>Something went wrong</h1>');
},
onError(error) {
didError = true;
console.error(error);
logServerCrashReport(error);
}
});

これは、初期のシェルコンテンツの生成䞭に既にシェルの倖偎で発生した゚ラヌが捕捉できるだけなので、完党ではありたせん。あるコンテンツで゚ラヌが発生したかどうかを知るこずが重芁であれば、それをシェルに移動させるこずができたす。


゚ラヌの皮類によっお凊理を分ける

カスタムの Error サブクラスを䜜成し、instanceof 挔算子を䜿甚しおどんな゚ラヌがスロヌされたかをチェックするこずができたす。䟋えば、カスタムの NotFoundError を定矩し、コンポヌネントからそれをスロヌするこずができたす。その埌、onError、onShellReady, onShellError のコヌルバック䞭で゚ラヌの皮類に応じお異なる凊理を行うこずができたす。

let didError = false;
let caughtError = null;

function getStatusCode() {
if (didError) {
if (caughtError instanceof NotFoundError) {
return 404;
} else {
return 500;
}
} else {
return 200;
}
}

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
response.statusCode = getStatusCode();
response.setHeader('content-type', 'text/html');
pipe(response);
},
onShellError(error) {
response.statusCode = getStatusCode();
response.setHeader('content-type', 'text/html');
response.send('<h1>Something went wrong</h1>');
},
onError(error) {
didError = true;
caughtError = error;
console.error(error);
logServerCrashReport(error);
}
});

しかしシェルを出力しおストリヌミングを開始しおしたうず、ステヌタスコヌドを倉曎できなくなりたすので泚意しおください。


クロヌラや静的生成向けに党コンテンツの読み蟌みを埅機する

ストリヌミングにより、利甚可胜になった順でコンテンツをナヌザが芋えるようになるため、ナヌザ䜓隓が向䞊したす。

しかし、クロヌラがペヌゞを蚪れた堎合や、ビルド時にペヌゞを生成しおいる堎合には、コンテンツを埐々に衚瀺するのではなく、党おのコンテンツを最初にロヌドしおから最終的な HTML 出力を生成したいでしょう。

onAllReady コヌルバックを甚いるこずで、すべおのコンテンツが読み蟌たれるたで埅機を行うこずができたす。

let didError = false;
let isCrawler = // ... depends on your bot detection strategy ...

const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/main.js'],
onShellReady() {
if (!isCrawler) {
response.statusCode = didError ? 500 : 200;
response.setHeader('content-type', 'text/html');
pipe(response);
}
},
onShellError(error) {
response.statusCode = 500;
response.setHeader('content-type', 'text/html');
response.send('<h1>Something went wrong</h1>');
},
onAllReady() {
if (isCrawler) {
response.statusCode = didError ? 500 : 200;
response.setHeader('content-type', 'text/html');
pipe(response);
}
},
onError(error) {
didError = true;
console.error(error);
logServerCrashReport(error);
}
});

通垞のナヌザは、ストリヌムで読み蟌たれるコンテンツを段階的に受け取りたす。クロヌラは、党デヌタが読み蟌たれた埌の最終的な HTML 出力を受け取りたす。しかし、これはクロヌラがすべおのデヌタを埅぀必芁があるこずを意味し、その䞭には読み蟌みが遅いものや゚ラヌが発生するものも含たれるかもしれたせん。アプリケヌションによっおは、クロヌラにもシェルを送信するこずを遞択しおも構いたせん。


サヌバレンダリングの䞭止

タむムアりト埌にサヌバでのレンダヌを「諊める」ように匷制するこずが可胜です。

const { pipe, abort } = renderToPipeableStream(<App />, {
// ...
});

setTimeout(() => {
abort();
}, 10000);

React は、残りのロヌディング䞭フォヌルバックを HTML ずしお盎ちに出力し、クラむアント䞊で残りをレンダヌしようず詊みたす。