I'm using create react app with react-snapshot to pre-render static markup for my routes. i.e "/", "/signIn", "/signUp"
generates index.html, signIn.html, signUp.html
respectively.
Issue I'm facing is that no matter what route I go to, initially the static index.html
generated from react-snapshot for the root route "/"
is served and then the correct static route file and then the main.js
bundle is served(see gif). This would be fine if I was just serving my app from a bundled main.js
alone. but since I want to use the static pre-generated html files, how do I disable the the service worker from serving index.html on certain routes for which I have static html file already.
Update: If I remove service worker from the create react app, the app loads static file for the path fine. However, I want to keep the functionality of service worker for PWA features.
Update 2: On chrome browser
the quick flicker of root route static markup happens only once for each route. After the 1st flicker it seems the chrome browser cache fixes it, additionally if I disable cache from chrome dev tools and try to go to new route the flicker of root route returns.
On Firefox browser
the problem exists no matter what, on every route change or refresh the momentary flick of root route static markup occurs.
How can I avoid the index.html to be rendered initially on all routes from the service worker without removing the service worker.
In more detail:
With the Service Worker active the following code renders in the body of page source of all routes:
<body>
<script>window.react_snapshot_state = {};</script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" data-react-checksum="-928641672"><div data-reactroot="" class="sc-cSHVUG hyLStb"><div class="sc-fjdhpX dIRAsX"><ul class="sc-gqjmRU koKaUp"><li><a class="navItemActive sc-VigVT cZrGwO" href="/"><!-- react-text: 6 --> <!-- /react-text --><!-- react-text: 7 -->Home<!-- /react-text --></a></li><li><a class="sc-VigVT cZrGwO" href="/aboutUs/"> About US</a></li><li><a class="sc-VigVT cZrGwO" href="/faq/"> FAQ</a></li></ul><div class="sc-jzJRlG cLytIk"><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="user circle icon"></i></button><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="add user icon"></i></button></div></div><!-- react-empty: 17 --><div><div style="opacity: 1;"><div class="sc-bdVaJa eRTdVS">Home</div></div></div></div></div><script type="text/javascript" src="/static/js/main.04df5475.js"></script></body>
IF I remove the Service worker the "/signIn"
route renders the following in the body of page source:
<body>
<script>window.react_snapshot_state = {};</script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" data-react-checksum="143569200"><div data-reactroot="" class="sc-cSHVUG hyLStb"><div class="sc-fjdhpX dIRAsX"><ul class="sc-gqjmRU koKaUp"><li><a class="sc-VigVT cZrGwO" href="/"><!-- react-text: 6 --> <!-- /react-text --><!-- react-text: 7 -->Home<!-- /react-text --></a></li><li><a class="sc-VigVT cZrGwO" href="/aboutUs/"> About US</a></li><li><a class="sc-VigVT cZrGwO" href="/faq/"> FAQ</a></li></ul><div class="sc-jzJRlG cLytIk"><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="user circle icon"></i></button><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="add user icon"></i></button></div></div><!-- react-empty: 17 --><div><div style="opacity: 1;"><div><div class="sc-EHOje bssfxk"><div class="sc-EHOje bssfxk"><form class="ui large warning form sc-ifAKCX ljuaXJ"><div class="field"><label></label><input type="email" placeholder="email" name="email" value=""></div><p class="sc-bxivhb dXOlfT">error</p></form><form class="ui large warning form sc-ifAKCX ljuaXJ"><div class="field"><label></label><input type="password" placeholder="password" name="password" value=""></div><p class="sc-bxivhb dXOlfT">error</p></form></div><p class="sc-dnqmqq ccTWaR"></p><div><div class="sc-gzVnrw cCgvhR"><button class="ui basic button sc-iwsKbI Vfjvd"><!-- react-text: 37 -->Login<!-- /react-text --><!-- react-text: 38 --> <!-- /react-text --></button><div class="sc-gzVnrw cCgvhR"><!-- react-empty: 40 --><div class="ui horizontal divider" style="width: 220px;">Or</div><div class="sc-bZQynM kECAnI"><button class="ui google plus button" style="text-transform: capitalize;"><i aria-hidden="true" class="google icon"></i><!-- react-text: 45 --> Google<!-- /react-text --></button><button class="ui facebook button" style="text-transform: capitalize;"><i aria-hidden="true" class="facebook icon"></i><!-- react-text: 48 --> Facebook<!-- /react-text --></button></div></div></div><div><p class="sc-htoDjs dErAlA">forgot your password ?</p></div></div></div></div></div></div></div></div><script type="text/javascript" src="/static/js/main.04df5475.js"></script><iframe style="display: none;"></iframe>
GiF shows me trying to access "/signIn"
Route, and notice the word home
(static markup for "/"
route) come up for a moment before the actual form for "/signIn"
route renders.
React-Static is a fast, lightweight, and powerful progressive static site generator based on React and its ecosystem. It resembles the simplicity and developer experience you're used to in tools like Create React App and has been carefully designed for performance, flexibility, and user/developer experience.
react-snap is a third-party library that pre-renders pages on your site into static HTML files.
React-static is a progressive static site generator based on React and its ecosystem. Because it is powerful, lightweight, and fast, it will be a great option for your next React app. React-static has been carefully designed for user/developer experience, flexibility, and performance.
The issue was that Service Worker(SW)
by default in Create React App
only caches contents of static folder
and the index.html
. My pre-rendered .html
files from react-snapshot were never cached by the SW
. the SW
in create react app
also is set to serve index.html
for all unknown urls, thus it was serving the root path "/"
static file index.html.
I solved this by overwriting the service-worker.js
file by changing the build command in package.json
like so:
"build": "react-scripts build && react-snapshot && sw-precache --config=sw-precache-config.js"
where my sw-precache-config.js
looked like the following:
module.exports = {
staticFileGlobs: [
'./build/**/**.html',
'./build/images/**.*',
'./build/static/**',
],
dontCacheBustUrlsMatching: /\.\w{8}\./,
swFilePath: './build/service-worker.js',
// For unknown URLs, fallback to the index page
navigateFallback: './200.html',
// Ignores URLs starting from /__ (useful for Firebase):
// https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
navigateFallbackWhitelist: [/^(?!\/__).*/],
// Don't precache sourcemaps (they're large) and build asset manifest:
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
stripPrefix: './build'
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With