I'm making react app to work offline for which I'm caching the files in sw.js file which is under public folder. The files are getting cached locally but when I'm deploying the app, it is not caching the files and giving the error - Uncaught (in promise) TypeError: Failed to execute 'addAll' on 'Cache': Request failed. Below is my sw.js file - ` let CACHE_NAME = "codePwa";
var urlCache = \[
"/manifest.json",
"/logo192.png",
"/",
"/index.html",
"/static/js/main.4d5113ea.js",
"/static/css/main.073c9b0a.css",
"./App.js",
\];
/// install service worker
this.addEventListener("install", (event) =\> {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) =\> {
return cache.addAll(urlCache);
})
);
});
// fetch cache data
this.addEventListener("fetch", (event) =\> {
if (!navigator.onLine) {
console.log("offline");
if (event.request.url === "http://localhost:3000/static/js/main.chunk.js") {
event.waitUntil(
this.registration.showNotification("modeNet", {
body: "Offline",
icon: "http://localhost:3000/logo192.png",
})
);
}
event.respondWith(
caches.match(event.request).then((response) =\> {
if (response) {
return response;
}
let fUrl = event.request.clone();
fetch(fUrl);
})
);
}
});
this.addEventListener("activate", function (event) {
event.waitUntil(
caches.keys().then(function (cacheNames) {
return Promise.all(
cacheNames
.filter(function (cacheNames) {
//
})
.map(function (cacheNames) {
return caches.delete(cacheNames);
})
);
})
);
});`
What changes should I make so that after deploying the app, it'll cache the files and when the app is offline and after refreshing the app fetch the file from the cache. I'm deploying my app on Netlify(url - https://calm-salmiakki-411347.netlify.app/)
This error causes when one or more URLs doesn't exist and cannot be found to be cached
I checked the urls and it seems that ./App.js
doesn't exist. if it's the App.js
of your react project, you don't need to cache it (because it doesn't exist in production). so remove it from your urlCache array
and if you are using cache first strategy you need to handle it with cache.open and then cache.match
so change this part :
event.respondWith(
caches.match(event.request).then((response) =\> {
if (response) {
return response;
}
let fUrl = event.request.clone();
fetch(fUrl);
})
);
to this :
event.respondWith(
caches.open(cacheName)
.then(function(cache) {
cache.match(event.request)
.then( function(cacheResponse) {
if(cacheResponse)
return cacheResponse
else
return fetch(event.request)
.then(function(networkResponse) {
cache.put(event.request, networkResponse.clone())
return networkResponse
})
})
})
)
and to be more organized, I rewrote your code
let CACHE_NAME = "codePwa";
var urlCache = [
"./manifest.json",
"./logo192.png",
"./",
"./index.html",
"./favicon.ico",
"./static/js/main.4d5113ea.js",
"./static/js/bundle.js",
"./static/css/main.073c9b0a.css",
"/about",
"/contact",
];
self.addEventListener('install', function (evt) {
console.log('The service worker is being installed.');
evt.waitUntil(precache());
});
function fromNetwork(request, timeout) {
return new Promise(function (fulfill, reject) {
var timeoutId = setTimeout(reject, timeout);
fetch(request).then(function (response) {
clearTimeout(timeoutId);
fulfill(response);
}, reject);
});
}
self.addEventListener('fetch', function (evt) {
if (!navigator.onLine) {
console.log("offline");
if (evt.request.url === "http://localhost:3000/static/js/main.chunk.js") {
evt.waitUntil(
this.registration.showNotification("modeNet", {
body: "Offline",
icon: "http://localhost:3000/logo192.png",
})
);
}
}
evt.respondWith(
fromNetwork(evt.request, 400).catch(() => fromCache(evt.request))
);
evt.waitUntil(update(evt.request));
});
function precache() {
return caches.open(CACHE_NAME).then(function (cache) {
return cache.addAll(urlCache);
});
}
function fromCache(request) {
return caches.open(CACHE_NAME).then(function (cache) {
return cache.match(request).then(function (matching) {
return matching || Promise.reject('no-match');
});
});
}
function update(request) {
return caches.open(CACHE_NAME).then(function (cache) {
return fetch(request).then(function (response) {
return cache.put(request, response);
});
});
}
self.addEventListener('activate', evt =>
evt.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) {
return caches.delete(cacheName);
}
})
);
})
)
);