4

In an Angular PWA I would like to redirect the user to a custom offline page (offline.html) if there is no internet connection available.

Using the ng-sw.config.json file I setup the assets and APIs to be cached and which strategy to use (performance/freshness) and I could serve the application even when offline without any problems. Now I would like to show a custom offline page, but among tutorials and guides I could not see a way to achieve this with Angular and its service-worker module.

I am wondering whether a possible solution would be to create a service that checks the connectivity (online/offline) and, if offline, it redirects to offline.html page. Service and html page would be cached with a 'prefetch' strategy to ensure they are available as soon as the service worker is installed.

Otherwise I would create a base service worker that imports the default Angular service worker and adds logic to redirect to the offline page if the fetch call fails.

Are there any other possibilities?

Tony Ngo
  • 19,166
  • 4
  • 38
  • 60
Francesco
  • 9,947
  • 7
  • 67
  • 110

1 Answers1

2

First you need to create a offline html page and store in assets folder.

Then add that offline page into your ng-sw.config like this

  "resources": {
    "files": [
      "/assets/favicon.ico",
      "/*.css",
      "/*.js",
      "/assets/offline-page.html"  
    ],

Next in your app.component.html add logic like this

ngOnInit() {
  self.addEventListener('fetch', function(event) {
    return event.respondWith(
      caches.match(event.request)
      .then(function(response) {
        let requestToCache = event.request.clone();

        return fetch(requestToCache).then().catch(error => {
          // Check if the user is offline first and is trying to navigate to a web page
          if (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html')) {
            // Return the offline page
            return caches.match(offlineUrl);
          }
        });
      })
    );
  });
}

So when user are in offline mode and user try to navigate to another route they will see offline page

Tony Ngo
  • 19,166
  • 4
  • 38
  • 60
  • so if I want to build an offline PWA with angular, I need to cache every file by myself!!? I thought Angular-cli will do this. – LiHao Jan 09 '20 at 10:33
  • It depend on what you need. In this case I only need 1 file offline-page.html why should I cache every file in asset folder ? – Tony Ngo Jan 09 '20 at 10:34
  • I want to cache the whole file, let this PWA like a native app, so I need to cache the whole file, but I can't figure out how to settings. Is any suggestion or keyword? – LiHao Jan 09 '20 at 10:46
  • @LiHao what do you mean for whole file ? – Tony Ngo Jan 09 '20 at 10:59
  • I want user use this app as a native app, it means this app can be used if there is no internet connection, maybe ajax will fail, but still can use. If it is a pure pwa web app I can do it, but angular-cli maybe have some specific setting, so I want to know. – LiHao Jan 09 '20 at 16:57
  • [document](https://angular.io/guide/service-worker-getting-started#getting-started-with-service-workers) I followed this document, but not work. I use @angular/cli@8.3.17 offline get ERROR 504 – LiHao Jan 10 '20 at 02:18
  • @LiHao please create a question and give me a link with the source code I will answer – Tony Ngo Jan 10 '20 at 03:44
  • 4
    I wonder, is this supposed to work? First, the code can be added to app.component.ts, not app.component.html. And then self.addEventListener('fetch'...) will only work in a service worker script, not inside app.component, right? https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent – Andriy Mar 16 '21 at 06:37
  • Followed exact code left here, but it doesn't work for me. I can't write this in app.component.ts (I figured .html was a typo)... respondWIth and .request are being labeled as errors and it feels like there's something missing – tz0 Jun 30 '21 at 07:24