Progressive Web App not working in offline mode

368 Views Asked by At

I enabled PWA for my reactjs application and deployed on my domain (arvind.inzack.com)

As part of testing, we installed the app on Samsung Tab device. Once the application is loaded successfully we disabled the wifi connection and reloaded the browser. The content in the App is not getting loaded.

we enabled all the files in the cache using Serviceworker.js

let CACHE_NAME = 'my-site-cache-v1';

const urlsToCache = [
'/',
'/index.html',
];

const precacheadd1Resources = ['/', '/shirt-trouser/shirts/.jpeg', '/shirt-trouser/shirts/.JPG', '/shirt-trouser/shirts/.PNG', '/shirt-trouser/shirts/.png'];
const precacheadd2Resources = ['/', '/shirt-trouser/trouser_plain/.jpeg', '/shirt-trouser/trouser_plain/.JPG', '/shirt-trouser/trouser_plain/.PNG', '/shirt-trouser/trouser_plain/.png'];
const precacheadd3Resources = ['/', '/shirt-trouser/belt/.jpeg', '/shirt-trouser/belt/.JPG', '/shirt-trouser/belt/.PNG', '/shirt-trouser/belt/.png'];

const precacheadd4Resources = ['/config.js', '/index.js','App.js','components/BabylonAvatar.js','components/SceneComponent.js'];
const precacheadd5Resources = ['/avatar/newformalwalk13.glb'];

window.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache, 
    precacheadd1Resources,
    precacheadd2Resources,
    precacheadd3Resources,
    precacheadd4Resources,
    precacheadd5Resources);
})
);
});

Please suggest how can we using the PWA App in offline mode.

I am trying with sw-toolbox cache, Using this link am trying to integrate

can somebody share the approach how to integrate sw-toolbox with with reactjs

Thanks Asha

2

There are 2 best solutions below

6
On

I see that you cache the resources, but activate and fetch listeners are missing. The fetch listener is triggered on each network request to cache and serve cached assets.

This is how my sw.js looks like:

const CACHE_VERSION = 'v1.17';
const CACHES = [{
  id: 'offline',
  name: `offline_${CACHE_VERSION}`,
  urls: [
    '/offline',
    '/manifest.json',
    '/icon/favicon.ico',
    '/icon/android-chrome-192x192.png',
    '/build/images/logo_white.svg'
  ]
}, {
  id: 'assets',
  name: `assets_${CACHE_VERSION}`,
  urls: []
}];
const CACHE_NAMES = CACHES.map(cache => cache.name);

// Triggered when no SW is yet registered to precache static assets
self.addEventListener('install', event => {
  self.skipWaiting();

  event.waitUntil((async () => {
    for (const myCache of CACHES) {
      const cache = await caches.open(myCache.name);
      console.info('[Service Worker] Precaching resources:', myCache.urls);
      await cache.addAll(myCache.urls);
    }
  })());
});

// Triggered when SW version updated to delete old cache
self.addEventListener('activate', event => {
  event.waitUntil((async () => {
    const cacheNames = await caches.keys();

    for (const cacheName of cacheNames) {
      if (CACHE_NAMES.indexOf(cacheName) === -1)) {
        console.info(`[Service Worker] Deleting cache: ${cacheName}`);
        await caches.delete(cacheName);
      }
    }
  })());
});

// Triggered on each network request to cache and serve cached assets
self.addEventListener('fetch', event => {
  event.respondWith((async () => {
    const { url, destination, mode } = event.request;
    let match, response;

    try {
      match = await caches.match(event.request);
      // serve cached if exist
      if (match) return match;
      // fetch and serve from network
      response = await fetch(event.request);
    } catch (err) {
      if (mode === 'navigate') {
        return await caches.match('/offline');
      }
    }

    if (['font', 'image', 'style', 'script'].includes(destination)) {
      const cacheName = CACHES.find(cache => cache.id === 'assets').name;
      const cache = await caches.open(cacheName);
      console.info(`[Service Worker] Caching new resource: ${url}`);
      await cache.put(event.request, response.clone());
    }

    return response;
  })());
});

Notice how I precached all the necessary resources for the offline mode, now in fetch listener:

  • I try to get a cached resource;

  • if resource is not cached - I try to fetch it;

  • if there is no internet connection - I request cached /offline page;

     try {
       match = await caches.match(event.request);
       // serve cached if exist
       if (match) return match;
       // fetch and serve from network
       response = await fetch(event.request);
     } catch (err) {
       if (mode === 'navigate') {
         return await caches.match('/offline');
       }
     }
    
1
On

You must add urls like this:

return cache.addAll([...urlsToCache, 
    ...precacheadd1Resources,
    ...precacheadd2Resources,
    ...precacheadd3Resources,
    ...precacheadd4Resources,
    ...precacheadd5Resources]);
})

You must add only one array in addAll method and like this you puth all urls in one array