Server Side Rendering to Strings

In notebook:
FrontEndMasters Intermediate React
Created at:
2019-06-24
Updated:
2019-08-15
Tags:
React libraries JavaScript Performance

https://frontendmasters.com/courses/intermediate-react-v2/server-side-rendering-to-strings/

Let's write the NodeJS server

  //    ****        server/index.js        ****

import express from "express";
import React from "react";
// this version renders to a Node Stream
import { renderToNodeStream } from "react-dom/server";
import { ServerLocation } from "@reach/router";
import fs from "fs";
import App from "../src/App";

const PORT = process.env.PORT || 3000;

// will read the output HTML
// for the server-side rendering
const html = fs.readFileSync("dist/index.html").toString();

// then split the HTML code two parts 
// the part before this sentence and part after
// so you will put the rendered markup between the two
const parts = html.split("not rendered");

// start a new Express server
const app = express();

// statically serve everything in the dist directory
app.use("/dist", express.static("dist"));

app.use((req, res) => {
  // we immediately write the first part of the page
  res.write(parts[0]);
  // THIS is how you render on the server side
  // with React
  const reactMarkup = (
    // this is from Reach router
    <ServerLocation url={req.url}>
      <App />
    </ServerLocation>
  );

  // this will start streaming the data
  const stream = renderToNodeStream(reactMarkup);
  stream.pipe(
    res,
    // we add end:false to no not to stop the stream
    { end: false }
  );
  stream.on("end", () => {
    // finally close with the last part when done
    res.write(parts[1]);
    res.end();
  });
});

console.log(`listening on ${PORT}`);
app.listen(PORT);

Rendering to a NodeJS stream

The idea is that the server can render by pieces or components and send them to the client as they are ready.