Zero-Configuration Static Prerendering for SPAs
react-snap is a zero-configuration, framework-agnostic static prerendering tool designed to convert Single Page Applications (SPAs) into static HTML. It leverages Headless Chrome (powered by Puppeteer) to crawl all navigable links from a given root, effectively generating static HTML files. This process significantly enhances SEO and initial page load performance by delivering pre-rendered content to the browser before JavaScript execution. The package is currently at version 1.23.0 and appears to be in a maintenance phase rather than active feature development, with its last major release dating back to early 2020. A key differentiator is its out-of-the-box compatibility with tools like Create React App and its ability to handle modern browser features without issue, as it uses a real browser for rendering. It primarily operates as a `postbuild` script, integrating into existing build workflows without requiring direct programmatic imports into the application's source code.
Common errors
-
Prerendering fails or results in blank pages when using hash-based URLs.
cause react-snap exclusively supports HTML5 history API for client-side routing, not hash-based routing.fixModify your application's router to use HTML5 history mode (e.g., `BrowserRouter` for React, `mode: 'history'` for Vue Router). -
Vue application rehydrates with a flash or renders incorrect initial state after prerendering.
cause Vue expects a `data-server-rendered` attribute on the root element for proper rehydration, which react-snap does not automatically add.fixAdd a `window.snapSaveState` callback in your application to manually set `document.querySelector('#app').setAttribute('data-server-rendered', 'true');` -
Generated HTML files appear broken, have incorrect spacing, or missing comments.
cause Aggressive `minifyHtml` settings (e.g., `collapseWhitespace` or `removeComments`) can inadvertently alter the DOM structure or remove critical elements.fixAdjust `minifyHtml` options in your `package.json` under the `reactSnap` key. Try disabling `collapseWhitespace` and `removeComments` if you encounter issues.
Warnings
- gotcha react-snap only supports routing strategies that utilize the HTML5 history API. It does not work with hash-based URLs (e.g., `/#/path`). Ensure your router is configured for history mode.
- gotcha When using Vue.js, rehydration can cause a flash due to the `data-server-rendered` attribute not being present on react-snap's output. A hack involving `window.snapSaveState` is often required.
- gotcha Custom `minifyHtml` options, particularly `collapseWhitespace` and `removeComments`, can sometimes lead to unexpected rendering issues or broken HTML, especially with frameworks like Vue.
Install
-
npm install react-snap -
yarn add react-snap -
pnpm add react-snap
Quickstart
yarn add --dev react-snap
// package.json
// ...
// "scripts": {
// "build": "react-scripts build",
// "postbuild": "react-snap"
// }
// ...
// src/index.js (for React 16+)
import { hydrate, render } from "react-dom";
import App from "./App"; // Assuming your main App component
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
hydrate(<App />, rootElement);
} else {
render(<App />, rootElement);
}