ServiceWorker is not updating, goes to skipwaiting in React app - reactjs

When I make a new production build of React app, new services worker installs but goes to skipwaiting state. So I have to hard reset cache on every build that is not good on live site.
I can't tell to every client, "please clear your cache to see latest". If I remove registerServiceWorker() from index file then build production do not detect my routes so it redirects to 404.

I used react-rewired-app boilerplate for my project and faced issue in that. Now I resolved that with a bunch of code in config-overrides.js file
config.plugins.forEach((obj) => {
if (obj.config) {
if (obj.config.clientsClaim) {
obj.config.skipWaiting = true
}
}
});

Related

How to clear browser cache in React Create App

I'm really struggling with Cache Busting on my Create React App.
I can see that the hash of my bundles are changing but users are still seeing old versions of the app on each deploy.
I've tried disabling the serviceworker
I've tried using the react-cache-buster
I'd be most grateful if anyone could talk me through their process of testing and implementing CacheBusting on a Create React App.
So far this is my code:
//App.js file
<CacheBuster
currentVersion={packInfo.version}
isEnabled={true} //If false, the library is disabled.
isVerboseMode={true} //If true, the library writes verbose logs to console.
>
// Load App() component here
Then in my index.js I'm not registering the Service Worker. I'm testing this in Chrome Console, and I can confirm that no Service Worker is being registered
// index.js
import App from './App'
ReactDOM.render(<App />, document.getElementById('root'))
Then I run npm run build followed by npm start
Then I go and check my browser network tab
Sometimes (I think) it is making the xhr request to meta.json and checking the version number in package.json
But it always outputs: There is no new version. No cache refresh needed.
When I deploy to Netlify on production I see the same log.
The HTML header have the following set:
cache-control: public, max-age=0, must-revalidate
Does anyone have any ideas how I can sort this problem out?

A website is not refreshing because of caching of service worker, after switching from React to Next.js. How to force update?

A website made on react had a service worker for caching. We ran the website with unregister() code and the website was ported to Next.js . Although on some machines, the unregister code never ran, so now those machines are running the old react code and not reflecting any changes made and pushed to the server. The changes are running on incognito and other machines where the unregister code ran. It is on Caddy server.
How can I force it to refresh from server side? We can clear cache or unregister the service worker on our machine but we don't know how many clients have the old code.
Thanks!
So the issue has been solved. Made a new service worker file, with just the code to remove the service worker.
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker.getRegistrations().then((registrations)
=> {
for (let registration of registrations) {
registration.unregister().then((bool) => {
console.log("unregister: ", bool);
});
}
});
});
}
And put this file in the exact location where the previous service worker was kept (You can find this out from the chrome developer tools). Also include the script tag linking this file in index.html or _document.js (for next.js). This should resolve the issue.
To solve this, the idea is to unregister the Service Worker of our React app so the browser can remove it. To do that, we have to create a Service Worker on the root of the Next.js project and add an EventListener — on any loaded page — to remove this file from the browser. Once we do this, we can be sure that next time a browser makes a request, it will be updated. Another important thing to note is that browsers need to close all the Service Worker’s instances associated with our app to apply the changes.
public/service-worker.js
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.getRegistrations().then(registrations => {
for(let registration of registrations) {
registration.unregister().then(bool => {console.log('unregister: ', bool);});
}
window.location.reload();
});
});
}
Source: https://www.asapdevelopers.com/service-worker-issue-nextjs-framework/

React - Unregistering a registered service worker

I'm developing a React web-app (https://timatorg.is - in case someone wants to look at the response headers) created using create-react-app. At the time it was created, a service worker was registered by default and I didn't really think much about it. The app is hosted at Netlify and the DNS is at Cloudflare.
Now when deploying updates to the website, users that have visited the site before always get the same version of the app and I'm pretty sure it's because of the service worker. But the strange thing is that it's only "https://www.timatorg.is" that is causing issues, not "https://timatorg.is"
I've read a lot of material about how to unregister an already cached service worker but all I've found is a solution that the client can perform in his/her browser but nothing that I can do to solve this for all of our clients.
So my question is, how do I get rid of the service worker? Or more general, push the latest update of our app to our clients?
You can change to the following in your index.js file, like the comment in a new Create React App project says:
import { unregister } from './serviceWorker';
// ...
unregister();
Add the following code into your index.js file:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
if (caches) {
// Service worker cache should be cleared with caches.delete()
caches.keys().then(async (names) => {
await Promise.all(names.map(name => caches.delete(name)));
});
}
});
}

users getting my previous bundle

I have a problem with my production website.
when users enter my website after building they getting a white screen.
I saw on the dev tools that the website trying to load the old bundle.js file and I don't understand why (the cashing is off)
This looks like a problem of a running service worker.
service worker is an API that cache your assets and other files so when a user is offline or having a slow network, he can still see your website.
React creates a service worker for you without your configuration by default, so this is the reason users enter your website and getting your previous bundle.
just put this in your app so next time user will enter your website, the service worker will be terminated.
import { unregister } from './registerServiceWorker';
// ....
unregister();
Service Workers, MDN
Service Workers, Google Web Fundamentals
Assuming you're using webpack to generate the builds and want caching (with service workers) to work as well, you can:
Add hashes to your generated bundles. Then, your webpack config may look like this:
{
output: {
path: path.resolve(__dirname, 'dist'),
filename: "[name].[chunkhash].js",
},
}
Read more about it here.
Do not cache your index.html which contains <script> imports of the updated hash-named bundles.
This will enable you to cache your builds easily, and only fetch new bundles whenever there is an update in the hash-names.

Redirect from http to https on localhost with create-react-app to test with Lighthouse

I have configured create-react-app to use https in my local development environment. I would now like to convert my React application to a progressive web app and I plan to use Lighthouse to check my status. I am running Lighthouse as a Chrome plugin, but I am having trouble with the part when it is checking if my HTTP requests are redirected to HTTPS. They are not.
I have been crawling through my node_modules and I have taken a look at webpack-dev-server that is bundled with create-react-app. I have tried to make some changes, but the best I have managed so far is that I have gotten "Too many redirects".
TL;DR: How can I configure create-react-app to redirect all requests from http to https on my local dev environment?
Here's the code from my create-react-app if you are having trouble with just the redirect part. I'm doing it manually since Heroku doesn't automatically handle it. But this actually needs to be handled on the server because it makes the app visibly load twice if it has to redirect to http. But for now, I'm redirecting in the constructor of my App component.
constructor(props, context) {
const url = window.location.origin
if (!url.includes('localhost') && !url.includes('https')) {
window.location = `https:${url.split(':'))[1]}`
}
}
For your purposes, you'd just need to take out the localhost part and make the new url a little differently (because of the port).
I'm using ramda here, but lodash also has a tail function you can use.
import { tail } from 'ramda
...
constructor(props, context) {
const url = window.location.origin
if (!url.includes('https')) {
window.location = `https:${tail(url.split(':')).join(':')}`
}
}
#Fmacs, for redirection of HTTP traffic to HTTPS, instead of using local dev-server, deploy your app on any environment like Heroku or Firebase. Firebase is very simple. I see that you also have other issues running the create-react-app that you created. I have explained how to do this in simple steps in a blog post with sample code in GitHub. Please refer to: http://softwaredevelopercentral.blogspot.com/2019/10/react-pwa-tutorial.html

Resources