workbox icon indicating copy to clipboard operation
workbox copied to clipboard

Workbox not refreshing new version

Open developdeez opened this issue 3 years ago • 7 comments

Im trying to show a new version of my web app even when its cached on the client machine

I've researched and have tried the method below. Trouble is, I pushed a new version of my site and visited on my phone and it still shows the old site.

Im using WorkBox as my sw and webpack in my react project.

Any ideas? Code location is in page-template.hbs

` // Check that service workers are supported if ('serviceWorker' in navigator && 'register' in navigator.serviceWorker) {

window.addEventListener('load', () => { navigator.serviceWorker.register('service-worker.js').then(reg => { reg.addEventListener('updatefound', () => {

    // An updated service worker has appeared in reg.installing!
    newWorker = reg.installing;


    newWorker.addEventListener('statechange', () => {

      // Has service worker state changed?
      switch (newWorker.state) {
        case 'installed':

          // There is a new service worker available, show the notification
          if (navigator.serviceWorker.controller) {
            newWorker.postMessage({ action: 'skipWaiting' });

          }
          break;
      }
    });
  });
});

});`

Library Affected: workbox webpack

Browser & Platform: Chrome

no error

developdeez avatar Feb 09 '22 20:02 developdeez

We normally point folks to https://developers.google.com/web/tools/workbox/guides/advanced-recipes#offer_a_page_reload_for_users as the "canonical" recipe for accomplishing this sort of thing.

I believe our friends at PWA Builder also have some pre-built solutions when it comes to UI for this.

Do either of those approaches work for you?

jeffposnick avatar Feb 09 '22 21:02 jeffposnick

@jeffposnick I took a look at PWA Builder and their Service worker looked a bit empty.

I created mine based on Recipes from the site you mentioned.

Do none of these allow the app to update on new version?

I thought their purpose was so we didn't have to add anything. If I need to look into something let me know but overall theres too much info to process :D

`import { pageCache, imageCache, staticResourceCache, googleFontsCache, offlineFallback } from 'workbox-recipes';

pageCache(); googleFontsCache(); staticResourceCache(); imageCache(); offlineFallback(); `

developdeez avatar Feb 12 '22 05:02 developdeez

Generally speaking, if you're using a cache-first service worker, you need to add something to your window context (i.e. the code run in your web app interface, not in the service worker) to coordinate updates. That's because by the time any revalidation/updates have happened in the caches maintained by the service worker, the contents of your web app have already loaded.

You could forcibly refresh each window client from within the service worker when you detect updates to cached resources, but it can easily confuse users who have already started interacting with your web page if they see all the content spontaneously reload. Showing some sort of warning in your web app's interface before triggering that reload ends up being less jarring.

jeffposnick avatar Feb 14 '22 19:02 jeffposnick

@jeffposnick that sounds great is there a React example of that? Trying to figure it out thru another package isn't feasible due to their framework

developdeez avatar Feb 15 '22 21:02 developdeez

I haven't used it personally, but there's https://www.npmjs.com/package/@loopmode/cra-workbox-refresh

jeffposnick avatar Feb 15 '22 21:02 jeffposnick

OK. Here's what I ended up with. Is this what you meant? :

 <script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>
   <script>
    // Check that service workers are supported
    if ('serviceWorker' in navigator && 'register' in navigator.serviceWorker) {

      window.addEventListener('load', () => {
        navigator.serviceWorker.register('service-worker.js').then(reg => {
          reg.addEventListener('updatefound', () => {
            // An updated service worker has appeared in reg.installing!
            newWorker = reg.installing;


            newWorker.addEventListener('statechange', () => {

              // Has service worker state changed?
              switch (newWorker.state) {
                case 'installed':

                  // There is a new service worker available, show the notification
                  if (navigator.serviceWorker.controller) {
                    newWorker.postMessage({ action: 'skipWaiting' });

                  }
                  break;
              }
            });
          });
        });
      });
    }
  </script>

developdeez avatar Feb 16 '22 02:02 developdeez

Hey, have you found the solution for this, I am using the create-react-app and workbox as well and ran into the same issue with the new index.html is not served.

I am using out from a box (no pun intended) code from cra with pwa. which has

precacheAndRoute(self.__WB_MANIFEST)

From my investigation so far, it looks like workbox doesn't give index html are new post fix __WB_REVISION. I did the following steps: 1 - Remove workbox pre cache 2 - Unregister the workbox via dev console 3 - Relead the page which re-register the service worker and new index.html is cached

Is there a way to have new __WB_REVISION postfix for every build?

Thanks

nnduc1994 avatar May 30 '23 17:05 nnduc1994