Browse Source

feat(sw.js): implement network-first strategy with cache fallback for fetch events to enhance offline capabilities and user experience

Mathias 1 month ago
parent
commit
ddc97b4c34
1 changed files with 31 additions and 4 deletions
  1. 31 4
      public/sw.js

+ 31 - 4
public/sw.js

@@ -11,6 +11,7 @@ const urlsToCache = [
 
 // Install event - cache resources
 self.addEventListener("install", (event) => {
+  self.skipWaiting(); // 🔥 force install
   event.waitUntil(
     caches.open(CACHE_NAME).then((cache) => {
       return cache.addAll(urlsToCache);
@@ -18,12 +19,38 @@ self.addEventListener("install", (event) => {
   );
 });
 
-// Fetch event - serve from cache when offline
+// Fetch event - network first with cache fallback
 self.addEventListener("fetch", (event) => {
   event.respondWith(
-    caches.match(event.request).then((response) => {
-      return response || fetch(event.request);
-    }),
+    fetch(event.request)
+      .then((response) => {
+        // If we get a valid response, clone it and update the cache
+        if (response && response.status === 200) {
+          const responseClone = response.clone();
+          caches.open(CACHE_NAME).then((cache) => {
+            cache.put(event.request, responseClone);
+          });
+        }
+        return response;
+      })
+      .catch(() => {
+        // If network fails, try to serve from cache
+        return caches.match(event.request).then((cachedResponse) => {
+          if (cachedResponse) {
+            return cachedResponse;
+          }
+          // If no cache available, return a custom offline page or error
+          if (event.request.destination === "document") {
+            return new Response("Application hors ligne - Veuillez vérifier votre connexion internet", {
+              status: 503,
+              statusText: "Service Unavailable",
+              headers: new Headers({
+                "Content-Type": "text/html; charset=utf-8",
+              }),
+            });
+          }
+        });
+      }),
   );
 });