go back

Perform a React disappearing act with react-snap ✨🧙💨

January 23, 2020

What if I told you I could build a frontend in React then compile & deploy it, without a server, as HTML without any trace of javascript?



It's remarkably easy to do for any static, non-interactive page. Here's how!

SSR & react-snap 👏

Server-side rendering (SSR) is not a new concept. Websites, especially high-traffic ones, have been doing this for years to optimize for pageload performance. This was always in the forefront when I was at GMG/The Onion, as a fast reading experience was paramount.

SSR in React-land usually this refers to doing something like this (taken from the react-snap readme):

import { hydrate, render } from "react-dom";

const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
  hydrate(<App />, rootElement);
} else {
  render(<App />, rootElement);
Enter fullscreen mode Exit fullscreen mode

The server performs the initial render then the client detects it and can just hydrate. But sometimes I don't want to hydrate, and instead prefer to completely abandon the code that got me there.

Luckily, there's a "zero-configuration framework-agnostic static prerendering" tool supports just that! react-snap uses puppeteer (headless Chrome) to virtually render the page, then does some additional optimizations.

Simply adding the package to any project with a build script (not just React, despite the name) and adding it as a postbuild script will enable it:

"scripts": {
  "postbuild": "react-snap"
Enter fullscreen mode Exit fullscreen mode

And this gets us half of the way. To get this to be asset-less we'll also need a few other flags:

"reactSnap": {
  "inlineCss": true,
  "removeBlobs": true,
  "removeScriptTags": true,
  "removeStyleTags": true
Enter fullscreen mode Exit fullscreen mode

Note: inlineCss is still an experimental feature and doesn't currently work because of a service worker issue. There's a patched version that includes a fix.

Now after running build, react-snap and minimalcss will turn the virtual DOM into actual DOM, strip out all the assets, and return plain old HTML!

Why this is cool 🔮


There is no dog, there is just snoot.

Not for every use case

Obviously this approach falls apart when you need any interactivity on the page. But this shines when you're rendering a static, read-only page (like a blog article) and don't need any other bloat.

Stay tuned for another post where I'll share a project that applies this with CI!

go back