Pre-renders web app into static HTML. Uses headless chrome to pre-render. Crawls all available links starting from the root. Heavily inspired by prep and react-snapshot, but written from scratch. Uses best practices to get best loading performance.
Does not depend on React. The name is inspired by react-snapshot
and because the initial goal was to enable seamless integration with create-react-app
. Actually, it works with any technology. Considering to change the name.
- Enables SEO (google, duckduckgo...) and SMO (twitter, facebook...) for SPA.
- Works out-of-the-box with create-react-app - no code-changes required.
- Uses real browser behind the scene, so no issue with unsupported HTML5 features, like WebGL or Blobs.
- Crawls all pages starting from the root, no need to list pages by hand, like in
prep
. - With prerendered HTML and inlined critical CSS you will get fast first paint, like with critical.
- With
Preload resources
feature you will get faster first interaction time if your page does do AJAX requests. - Works with webpack 2 code splitting feature
- Handles sourcemaps
- Supports non-root paths (eg for create-react-app relative paths)
Please note: some features are experimental, but basic prerendering is considered stable enough. API is subject to change before freeze in version 1.0
.
Install:
yarn add --dev react-snap
Change package.json
:
"scripts": {
"build": "react-scripts build && react-snap"
}
Change src/index.js
(for React 16+):
import { hydrate, render } from 'react-dom';
const rootElement = document.getElementById('root');
if (rootElement.hasChildNodes()) {
hydrate(<App />, rootElement);
} else {
render(<App />, rootElement);
}
That's it!
If you need to pass some options for react-snap
, you can do this in the package.json
, like this:
"reactSnap": {
"inlineCss": true
}
All options are not documented yet, but you can check defaultOptions
in index.js
.
Experimental feature - requires improvements.
react-snap
can inline critical CSS with the help of minimalcss and full CSS will be loaded in a nonblocking manner with the help of loadCss.
Use inlineCss: true
to enable this feature.
TODO: as soon as the feature will be stable it should be enabled by default. As of now <noscript>
fallback not implemented.
Experimental feature - requires improvements.
react-snap
can capture all required resources on the page and modify HTML, to instruct a browser to preload those resources.
- It will use
<link rel="preload" as="image">
for images. - it will store
json
request to the same domain inwindow.snapStore[<path>]
, where<path>
is the path of json request
Use preloadResources: true
to enable this feature.
See recipes for more examples.
You can block all third-party requests with the following config
"skipThirdPartyRequests": false
Headless chrome does not fully support WebGL, if you need render it you can use
"headless": false
Puppeteer (headless chrome) may fail due to sandboxing issues. To get around this, you may use
"puppeteerArgs": ["--no-sandbox", "--disable-setuid-sandbox"]
Read more about puppeteer troubleshooting.
If you get following error Uncaught ReferenceError: webpackJsonp is not defined
, you can use the following hack
"fixWebpackChunksIssue": true
TODO: as soon as the feature will be stable it should be enabled by default.
If you get an error in a production build, you can use sourcemaps to decode stack trace:
"sourceMaps": true
TODO: as soon as the feature will be stable it should be enabled by default.
- Update recipes based on the code of stereobooster/an-almost-static-stack
- Improve preconnect, dns-prefetch functionality, maybe use media queries. Example: load in small screen - capture all assets, add with a media query for the small screen, load in big screen add the rest of the assets with a media query for the big screen.
- Do not load assets, the same way as minimalcss does
- Evaluate penthouse as alternative to minimalcss
- Webcomponents SSR
- prerender/prerender
- Simple express server for your Create React App projects with Server-side rendering and Code-splitting. It seems it is similar to razzle - two webpack configs.