import * as ReactDOMServer from 'react-dom/server'; import cookie from 'cookie'; import config from 'config'; // import our main App component import App from '../../src/App'; import { getLinks } from '../sape'; import { StaticRouter } from 'react-router-dom/server'; import { VisitorProvider } from '../../src/ui/VisitorContext'; import path from 'path'; import fs from 'fs'; // convert a Unicode string to a string in which // each 16-bit unit occupies only one byte function toBinary(string) { const codeUnits = new Uint16Array(string.length); for (let i = 0; i < codeUnits.length; i++) { codeUnits[i] = string.charCodeAt(i); } return Buffer.from(String.fromCharCode(...new Uint8Array(codeUnits.buffer))).toString('base64'); } const STATIC_ROOT = config.get('service.static_root') || path.resolve(__dirname, 'public'); const serverRenderer = async (req, res) => { // point to the html file created by CRA's build tool const filePath = path.resolve(STATIC_ROOT, 'index.html'); // links const cookies = cookie.parse(req.headers.cookie || ''); const links = await getLinks(req.originalUrl, cookies['sape_cookie']); fs.readFile(filePath, 'utf8', (err, htmlData) => { if (err) { console.error('err', err); return res.status(404).end(); } const routerContext = {}; const props = { footer: links.join(' ') }; const marker = '
'; const data = htmlData.split(marker); const propsData = `${marker}`; let didError = false; const { pipe } = ReactDOMServer.renderToPipeableStream( , { onShellReady() { res.statusCode = didError ? 500 : 200; res.setHeader('Content-type', 'text/html'); res.write(data[0]); res.write(propsData); pipe(res, { end: false }); }, onShellError() { didError = true; res.statusCode = 500; res.setHeader('Content-type', 'text/html'); res.send( '

Something went wrong :(

' ); res.end(); }, onAllReady() { if (!didError) { res.write(data[1]); } res.end(); }, onError(err) { didError = true; console.log(err); } }); }); }; export default serverRenderer;