main
js 57 lines 1.63 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 */
8
9 import * as React from 'react';
10 import {renderToPipeableStream} from 'react-dom/server';
11 import App from '../src/App';
12 import {ABORT_DELAY} from './delays';
13
14 // In a real setup, you'd read it from webpack build stats.
15 let assets = {
16 'main.js': '/main.js',
17 'main.css': '/main.css',
18 };
19
20 module.exports = function render(url, res) {
21 // The new wiring is a bit more involved.
22 res.socket.on('error', error => {
23 console.error('Fatal', error);
24 });
25 let didError = false;
26 let didFinish = false;
27 const {pipe, abort} = renderToPipeableStream(<App assets={assets} />, {
28 bootstrapScripts: [assets['main.js']],
29 onAllReady() {
30 // Full completion.
31 // You can use this for SSG or crawlers.
32 didFinish = true;
33 },
34 onShellReady() {
35 // If something errored before we started streaming, we set the error code appropriately.
36 res.statusCode = didError ? 500 : 200;
37 res.setHeader('Content-type', 'text/html');
38 setImmediate(() => pipe(res));
39 },
40 onShellError(x) {
41 // Something errored before we could complete the shell so we emit an alternative shell.
42 res.statusCode = 500;
43 res.send('<!doctype><p>Error</p>');
44 },
45 onError(x) {
46 didError = true;
47 console.error(x);
48 },
49 });
50 // Abandon and switch to client rendering if enough time passes.
51 // Try lowering this to see the client recover.
52 setTimeout(() => {
53 if (!didFinish) {
54 abort();
55 }
56 }, ABORT_DELAY);
57 };