diff --git a/src/scripts/register-sw.js b/src/scripts/register-sw.js
index 0f10ec95e5724d4ed70cf09f69ec927eeb901814..5b375a824fabba7c2a2d7a6104debc5293236939 100644
--- a/src/scripts/register-sw.js
+++ b/src/scripts/register-sw.js
@@ -1,5 +1,11 @@
-document.addEventListener("DOMContentLoaded", function () {
-  if('serviceWorker' in navigator) {
-    navigator.serviceWorker.register('/sw.js');
-  }
-});
\ No newline at end of file
+if('serviceWorker' in navigator) {
+  var refreshing;
+  navigator.serviceWorker.addEventListener('controllerchange', () => {
+      if (refreshing) {
+          return;
+      }
+      refreshing = true;
+      window.location.reload();
+  });
+  navigator.serviceWorker.register('/sw.js');
+}
\ No newline at end of file
diff --git a/src/sw.js b/src/sw.js
index 200384bb1c48506295b0e93af490bfd0109f08f8..b8cac042bd64199af23f84ee410200272662e45d 100644
--- a/src/sw.js
+++ b/src/sw.js
@@ -1,74 +1,111 @@
+const CACHE_NAME = 'hubl-store-dev';
+
 self.addEventListener('install', function (e) {
   e.waitUntil(
-    caches.open('hubl-store').then(function (cache) {
+    caches.open(CACHE_NAME).then(function (cache) {
       return cache.addAll([
-        '/components/hubl-reactivity.js',
-        '/components/hubl-search-users.js',
-        '/components/hubl-status.js',
-        '/components/sentry.js',
-        '/fonts/custom-icons.eot',
-        '/fonts/custom-icons.svg',
-        '/fonts/custom-icons.ttf',
-        '/fonts/custom-icons.woff',
-        '/fonts/FacitBold.eot',
-        '/fonts/FacitBold.svg',
-        '/fonts/FacitBold.ttf',
-        '/fonts/FacitBold.woff',
-        '/fonts/FacitRegular.eot',
-        '/fonts/FacitRegular.svg',
-        '/fonts/FacitRegular.ttf',
-        '/fonts/FacitRegular.woff',
-        '/fonts/material-design-icons.eot',
-        '/fonts/material-design-icons.svg',
-        '/fonts/material-design-icons.ttf',
-        '/fonts/material-design-icons.woff',
-        '/fonts/material-design-icons.woff2',
-        '/fonts/RefrigeratorDelxW01Bold.eot',
-        '/fonts/RefrigeratorDelxW01Bold.svg',
-        '/fonts/RefrigeratorDelxW01Bold.ttf',
-        '/fonts/RefrigeratorDelxW01Bold.woff',
-        '/fonts/simple-line-icons.eot',
-        '/fonts/simple-line-icons.svg',
-        '/fonts/simple-line-icons.ttf',
-        '/fonts/simple-line-icons.woff',
-        '/fonts/simple-line-icons.woff2',
-        '/images/add-user.svg',
-        '/images/alien.svg',
-        '/images/appointment.svg',
-        '/images/arrow-down.svg',
-        '/images/calendar.svg',
-        '/images/chevron-down.png',
-        '/images/favicon.png',
-        '/images/file.svg',
-        '/images/hubl-icon-192.png',
-        '/images/hubl-icon-512.png',
-        '/images/logo.png',
-        '/images/send.png',
-        '/images/vote.svg',
         '/locales/es.json',
         '/locales/fr.json',
         '/scripts/index.js',
         '/syles/index.css',
         '/index.html',
-        '/manifest.webmanifest',
         '/'
       ]);
     })
-  );
+  ).then(() => e.skipWaiting());
 });
 
-//TODO: Can't use fetch because of unpkg, e.request is missing a part of the package name "@startinblox/core" become "@startinblox"
-self.addEventListener('fetch', function (e) {
-  // Handle direct loading /xyz/ when server is unjoinable
-  if (e.request.mode === 'navigate') {
-    e.respondWith(caches.match('/'));
-    return;
+self.addEventListener('activate', function (e) {
+  // invalidate older versions
+  e.waitUntil(
+    caches.keys()
+    .then(function (keyList) {
+      return Promise.all(keyList.map(function (key) {
+        if (key !== CACHE_NAME && key !== (CACHE_NAME + "-cdn") && key !== (CACHE_NAME + "-api")) {
+          return caches.delete(key);
+        }
+      }));
+    }));
+  self.clients.claim();
+});
+
+self.addEventListener('fetch', function (event) {
+  let requestURL = new URL(event.request.url);
+  if (requestURL.origin == location.origin) {
+    // Static asset, cache then network
+    event.respondWith(
+      caches.open(CACHE_NAME).then(function (cache) {
+        return cache.match(event.request).then(function (response) {
+          var fetchPromise = fetch(event.request).then(function (networkResponse) {
+            cache.put(event.request, networkResponse.clone());
+            return networkResponse;
+          });
+          return response || fetchPromise;
+        });
+      }),
+    );
+  } else {
+    if (
+      event.request.method == 'POST' ||
+      event.request.method == 'PUT'
+    ) {
+      // disabled: lead to cors errors
+      // // POST/PUT to api, rewrite the cache
+      // event.respondWith(
+      //   caches.open(CACHE_NAME + '-api').then(function (cache) {
+      //     return fetch(event.request).then(function (response) {
+      //       cache.put(event.request, response.clone());
+      //       return response;
+      //     })
+      //   }));
+      // api: no cache
+      event.respondWith(fetch(event.request));
+    } else if (
+      /matomo/.test(requestURL.origin) ||
+      /sentry/.test(requestURL.origin) ||
+      /jabber/.test(requestURL.origin) ||
+      /xmpp/.test(requestURL.origin)
+    ) {
+      // analytics, always distant
+      event.respondWith(fetch(event.request));
+    } else {
+      if (
+        /unpkg/.test(requestURL.origin) ||
+        /jspm/.test(requestURL.origin) ||
+        /jsdeliver/.test(requestURL.origin) ||
+        /cdn/.test(requestURL.origin) ||
+        /googleapis/.test(requestURL.origin)
+      ) {
+        // cdn: cache then network
+        event.respondWith(
+          caches.open(CACHE_NAME + '-cdn').then(function (cache) {
+            return cache.match(event.request).then(function (response) {
+              var fetchPromise = fetch(event.request).then(function (networkResponse) {
+                cache.put(event.request, networkResponse.clone());
+                return networkResponse;
+              });
+              return response || fetchPromise;
+            });
+          }),
+        );
+      } else {
+        // disabled: lead to cors errors
+        // // api: distant then cache
+        // event.respondWith(
+        //   fetch(event.request)
+        //   .then((response) => {
+        //     caches.open(CACHE_NAME + '-api').then(function (cache) {
+        //       cache.put(event.request, response.clone());
+        //       return response;
+        //     });
+        //   })
+        //   .catch(() => {
+        //     return caches.match(event.request);
+        //   })
+        // );
+        // api: no cache
+        event.respondWith(fetch(event.request));
+      }
+    }
   }
-  e.respondWith(
-    fetch(e.request, {
-      credentials: 'include'
-    }).catch(function() {
-      return caches.match(e.request);
-    })
-  );
 });
\ No newline at end of file