Migrating from Dfinity to Own Infrastructure: Service Worker Challenges and Seeking Solutions

Hello Dfinity community,

I recently made the decision to host my website on Dfinity and everything was working perfectly until the recent bugs. Given these challenges, I decided to shift and host my site on my own infrastructure.

However, I ran into a significant roadblock. After changing the DNS from mon.domaine.com CNAME ic0.app to my server’s IP, my site stopped working. After some digging, I realized that the issue stemmed from Dfinity’s utilization of service workers. The worker service, which runs before my site code, malfunctions when I change my registrar and my whole site is broken.

To address this, I attempted to incorporate the following code:

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

Additionally, I added these HTTP response headers:

Cache-Control: "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
Clear-Site-Data: "\"cache\""

But here’s the catch - my website isn’t even contacted, and since the service worker fails, the above solutions don’t work.

Locally, I found a workaround by removing the service worker which gets things back on track. But how can I ensure a seamless experience for my users? It’s unrealistic and unreasonable to expect them to undertake these steps manually.

Has anyone else faced a similar issue? I’m keen to hear any solutions that would not require any action on the user’s end. Any suggestions or insights would be greatly appreciated!

Thank you!

Gautier


Hi @Gwojda,

Browsers in the background when you navigate to a page that has a service worker will ask the server for an updated version of the service worker, in the case for the default service worker the the Boundary Node provides, that would be /sw.js.

If you’re moving to your own infrastructure and want to remove the service worker in favour of a different HTTP Gateway implementation, you can simply add an uninstall script under that /sw.js path, your web server would deliver that to the browser (you can use this as a reference) and that will remove the current service worker and refresh the page.

Are you using a custom HTTP Gateway implementation or simply forking the service worker? if the later is the case, you need to make sure that your web server complies with the HTTP Gateway Protocol and adds the x-ic-canister-id header to HEAD requests that the service worker will use to know from which canister to load the assets.

4 Likes

Hi Kepler, thanks for your reply.

  • x-ic-canister-id: I’m not sure it was needed, i still had _canister-id -subdomain in txt record setted. And even with this record it wasn’t worked.

  • i tried to add sw.js with a default service worker :

self.addEventListener('install', function(event) {
    console.log('Service Worker installed');
  });
  
  self.addEventListener('activate', function(event) {
    console.log('Service Worker activated');
  });
  

But didn’t worked.

  • I didn’t tried yet the uninstall script, but what shall i do ? add a sw.js files in my root directory with
self.addEventListener('install', () => self.skipWaiting());
self.addEventListener('activate', () => {
  // uninstall itself & reload page
  self.registration
    .unregister()
    .then(function () {
      return self.clients.matchAll();
    })
    .then(function (clients) {
      clients.forEach((client) => {
        client.navigate(client.url);
      });
    });
});

?

Again, thanks for your help,
Gautier

This is only used by the boundary node with their custom domain implementation, if you’re moving to your own infrastructure you don’t need that.

Yes, that should be it to uninstall the active service worker and reload the active window clients.

But you still need to have some implementation of the HTTP Gateway Protocol to be able to communicate with your canister to translate between the IC Api calls and the HTTP response that the browser is expecting.

thanks you Kepler, worked !