241

After deleting /serviceworker.js from my root directory, Chrome still runs the service worker that I removed from my webroot. How do I uninstall the service worker from my website and Chrome so I can log back into my website?

I've tracked the issue down to Service Work's cache mechanism and I just want to remove for now until I have time to debug it. The login script that I'm using redirects to Google's servers for them to login to their Google account. But all I get from the login.php page is an ERR_FAILED message.

1
  • 4
    I have the same issue in Firefox. Commented Feb 2, 2017 at 19:50

21 Answers 21

459

Removing Service Workers Programmatically:

You can remove service workers programmatically like this:

navigator.serviceWorker.getRegistrations().then(registrations => {
    for (const registration of registrations) {
        registration.unregister();
    } 
});

Docs: getRegistrations, unregister

Removing Service Workers Through The User Interface

You can also remove service workers under the Application tab in Chrome Devtools.

14
  • 15
    Is there anytime time-based around this? Say a user visited once, registered the worker, and hasn't come back since, do I need to keep this snippet in our codebase forever just in case? Commented Aug 2, 2016 at 18:45
  • 4
    Verbose version: gist.github.com/mrienstra/9c60a76009480e2240770dadb2fb96fe
    – mrienstra
    Commented Feb 4, 2018 at 22:11
  • 12
    I have a blog post reviewing this and other service worker remove/uninstall options love2dev.com/blog/how-to-uninstall-a-service-worker
    – Chris Love
    Commented Feb 12, 2018 at 13:59
  • 8
    How would that help? The page is already cached by the installed worker and your new script will never be fetched by the users.
    – riv
    Commented Aug 2, 2019 at 16:50
  • 3
    The following article discusses a potential issue with this answer's code and suggests an alternative: medium.com/@nekrtemplar/…
    – sammy34
    Commented Oct 22, 2020 at 9:08
128

You can also go to the URL: chrome://serviceworker-internals/ and unregister a serviceworker from there.

3
  • 12
    You can type this into dev console to unregister all of them in one fell swoop. document.querySelectorAll(".unregister").forEach(item=>item.click())
    – senbon
    Commented Jun 8, 2019 at 13:34
  • However, if you have other visitors that you need to unregister as well (friends, users, project managers, etc.), the answer above (by Daniel Herr) is more of an effective solution. You've also got Firefox, Edge and Safari, as well, in flavors of iOS, Android, macOS, Windows 10 for each to test. Commented Jul 20, 2019 at 20:25
  • $$('.unregister').forEach(item => item.click()) Commented Mar 11, 2020 at 13:34
52

You can do this through Chrome Developer Tool as well as Programatically.

  1. Find all running instance or service worker by typing

    chrome://serviceworker-internals/

    in a new tab and then select the serviceworker you want to unregister.

  2. Open Developer Tools (F12) and Select Application. Then Either

    Select Clear Storage -> Unregister service worker

    or

    Select Service Workers -> Choose Update on Reload

  3. Programatically

if(window.navigator && navigator.serviceWorker) {
  navigator.serviceWorker.getRegistrations()
  .then(function(registrations) {
    for(let registration of registrations) {
      registration.unregister();
    }
  });
}

0
24

In Google Chrome, you can go to Developer tools (F12) -> Application -> Service worker and unregister the service workers from the list for that specific domain.

Screenshot

This method is effective in development mode of a site and mostly they run on localhost which is you may need for other project's development.

9

FYI, in case you are using MacOS Safari browser, there is one way to forcibly unregister a service worker (steps and images for Safari 12.1):

  1. Safari > Preferences... > Privacy > Manage Website Data… Safari Preferences : Privacy

  2. Enter domain name (ex. 'localhost'), click "Remove" Safari Preferences : Privacy : manage website data

Note: In addition to service workers, this also will erase all caches, cookies, and databases for this domain.

2
  • Looks like this doesn't work if the service workers were installed via a Private Window.
    – aris
    Commented Mar 6, 2020 at 13:47
  • @aris that's irritating giving Apple should be transparent, it is not even clear about the common websites' installed service workers.
    – Machado
    Commented Dec 22, 2022 at 20:03
7

In addition to the already correct answers given, if you want also to delete the SW cache you can invoke the following method:

if ('caches' in window) {
    caches.keys()
      .then(function(keyList) {
          return Promise.all(keyList.map(function(key) {
              return caches.delete(key);
          }));
      })
}


More in this article (Paragraph: "Unregister a service worker")


Another possibility, via Browser, is by accessing the "Cache Storage" section and click on the "Clear Site Data" button:

enter image description here

5

You should detecte two API in your devices: getRegistrations and getRegistration. The service-worker not has a unique set of APIs in all platforms. For example, some browsers only have a navigator.serviceWorker.getRegistration, no navigator.serviceWorker.getRegistrations. So you should consider with both.

5

IF your service worker don't let you update your files. You will need to replace serviceworker file (sw.js / ServiceWorker.js) with the next code:

self.addEventListener('install', function(e) {
  self.skipWaiting();
});

self.addEventListener('activate', function(e) {
  self.registration.unregister()
    .then(function() {
      return self.clients.matchAll();
    })
    .then(function(clients) {
      clients.forEach(client => client.navigate(client.url))
    });
});

Source here

3

safely uninstall Service Worker

if ('serviceWorker' in navigator) {
      navigator.serviceWorker.getRegistrations().then(function (registrations) {
        for (const registration of registrations) {
          // unregister service worker
          console.log('serviceWorker unregistered');
          registration.unregister();
        }
      });
    }
3

to detect service worker:

navigator.serviceWorker.controller

Code to for deletion of service worker:

navigator.serviceWorker.getRegistrations()
  .then(registrations => {
    registrations.forEach(registration => {
      registration.unregister();
    })
  });

  navigator.serviceWorker.getRegistrations().then(function(registrations) {
   for(let registration of registrations) {
    registration.unregister()
  } })

  if(window.navigator && navigator.serviceWorker) {
    navigator.serviceWorker.getRegistrations()
    .then(function(registrations) {
      for(let registration of registrations) {
        registration.unregister();
      }
    });
  }

  if ('caches' in window) {
      caches.keys()
        .then(function(keyList) {
            return Promise.all(keyList.map(function(key) {
                return caches.delete(key);
            }));
        })
  }

  if ('serviceWorker' in navigator) {
        navigator.serviceWorker.getRegistrations().then(function (registrations) {
          for (const registration of registrations) {
            // unregister service worker
            console.log('serviceWorker unregistered');
            registration.unregister();

            setTimeout(function(){
              console.log('trying redirect do');
              window.location.replace(window.location.href); // because without redirecting, first time on page load: still service worker will be available
            }, 3000);
          }
        });
      }
3

as for me , i just use a new nonexistent scope service worker to replace old one,

ServiceWorker: {
        events: true,
        // what range of URLs a service worker can control. Use a nonexistent path to disable ServiceWorker
        scope: '/disable-service-worker/',
      },

as for the app.js, i add below code to unregister old sw:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.getRegistrations().then(registrations => {
    for (const registration of registrations) {
      // keep only serviceWorker which scope is /disable-service-worker/, The purpose is to make serviceWorker useless
      if (registration.scope.includes('/disable-service-worker/') === false) {
        registration.unregister()
      }
    }
  });
  // clear cache of service worker
  caches.keys().then(keyList => {
    return Promise.all(
      keyList.map(key => {
        return caches.delete(key);
      }),
    );
  });
}
3

If, like me, you need to unregister a service worker after deploying an entirely new codebase at the same domain (without a service worker), the solution is to create a new service worker at the same location and disable all caching:

self.addEventListener('fetch', event => event.respondWith(fetch(event.request)))

This way, when the browser asks for sw.js (or whatever you named it), it will get the new one, then load your new site from the network. After an indeterminate time (i.e. after all your users have loaded the new service worker), you can remove the service worker.

2

The other answers all add code to the live website to remove the service worker. However I didn't want to leave that live code running forever so I developed a solution that works from within the service worker itself. The steps are below, I posted more detail and explanation on my blog.

  1. Delete the code that registers the service worker.
  2. Replace the service worker script with the following file. The new code must be available from the same URL the previous service worker was at. If you had multiple service worker URLs in the past you should duplicate the code at all of them.
console.log("Cleanup Service Worker Starting");

caches.keys()
    .then(keys =>
        Promise.all(
            keys.map(async key => console.log("caches.delete", key, await caches.delete(key)))))
    .then(async () => {
        console.log("registration.unregister", await registration.unregister());
    })
    .then(() => console.log("DONE"))
    .catch(console.error);

This code is fairly straight forward. First it deletes all the caches, then it unregisters itself.

Users' browsers will automatically check for an updated service worker the next time they load your website, or the next event 24h after the last service worker check. This means that existing users will run this cleanup on their next visit.

2

It can also be done in Chrome through application tab: enter image description here

1

This code is compatible with Internet Explorer:

if (navigator.serviceWorker) {
    navigator.serviceWorker.getRegistrations().then(                
        function(registrations) {
            for (let idx in registrations) {
                registrations[idx].unregister()
            }
        })
}

IE doesn't support 'for...of' and 'for...of' construction may lead to "'SCRIPT1004: Expected ';'" error

1

If You want to unregister all of the registered service workers in Browser, you can do it by opening ex.

  • Chrome: chrome://serviceworker-internals/
  • Brave brave://serviceworker-internals/

open DevTools > Console and paste this:

$$('.unregister').forEach(b => b.click())
1

I'm using Brave. None of the provided answers worked for me on a page with a single service worker.

  • navigator.serviceWorker.getRegistrations() stays pending.
  • navigator.serviceWorker.getRegistration() stays pending.
  • navigator.serviceWorker.getRegistration(navigator.serviceWorker.controller.scriptURL) stays pending
  • navigator.serviceWorker.ready is fulfilled immediately unless there is no service worker registered for the current page

I used this:

(await navigator.serviceWorker.ready).unregister()
1

You can delete all service workers in Chrome in a second:

  1. Go to chrome://serviceworker-internals
    or if using brave then go to brave://serviceworker-internals

  2. In the console, enter the following code:

    $$('.unregister').forEach(b => b.click())

This code will click on the "unregister" button for each service worker, effectively deleting all of them :)

1
0

Open this page: chrome://serviceworker-internals and click to unregister button.

If you want to unregister all service worker open the developer tools and run this code on above page.

document.querySelectorAll("button.unregister").forEach(item=>{ item.click()})
0

Open in Chrome

chrome://serviceworker-internals/?devtools

then F12 in Console

$$('.unregister').forEach(b => b.click())

0

Typical JavaScript loop thats compatible with everything:

navigator.serviceWorker.getRegistrations().then(function(registrations) {
    var registrationslength = registrations.length;
    for (var i = 0; i < registrationslength; i++) {
        registrations[i].unregister();
    }
})

Not the answer you're looking for? Browse other questions tagged or ask your own question.