'How to use ReactDOMServer.renderToStaticMarkup without nodejs server

I want to use ReactDOMServer.renderToStaticMarkup to create a static website, but I only want to generate the html string once during build instead of dynamically for every request

Here are the relevant docs, but they don't go into much detail on implementation https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup

What is the best practice for using react to generate html one time during build instead of dynamically on every page request? I am using webpack.



Solution 1:[1]

For anyone who comes here looking for answers, here's how I did it:

  1. Create a separate webpack config file for your SSR react like webpack.ssr.js. This file will have the same config you'd normally have for react SSR.
  2. In the index.js file where you'd usually have ReactDOM.render, run the ReactDOMServer.renderToStaticMarkup function.
  3. In the index.js file, write the html string to a file:
const html = ReactDOMServer.renderToStaticMarkup(App);

fs.writeFile("index.html", html, (err) => {
  if (err)
    console.log(err);
  else {
    console.log("File written successfully\n");
  }
});
  1. After every build, execute the build file as a node script. For example node build.js. I'd recommend doing this in package.json as a postbuild script. For example:
postbuild: "node build.js"
  1. The fs.writeFile will update the index.html file each time you build, so you'll just need to serve index.html like you would with any other static website.

  2. For css modules, you'd use something like isomorphic-style-loader instead of the regular style-loader.

  3. If you are using something like react-router, you'll need to iterate through all your routes and run ReactDOMServer.renderToStaticMarkup and fs.writeFile for every route. Then you'd serve the different html files with server side routing.

  4. This will also work for normal SSR using ReactDOMServer.renderToString, especially if you don't need dynamic SSR based on something like an ID. For generating the loading screen server side, this is great and there's really no reason to generate html dynamically at runtime.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jeremy Gottfried