Skip to content

Instantly share code, notes, and snippets.

@Antoinebr
Last active June 18, 2020 14:57
Show Gist options
  • Save Antoinebr/d5867bda78ec4edee627a86dba2ce7a9 to your computer and use it in GitHub Desktop.
Save Antoinebr/d5867bda78ec4edee627a86dba2ce7a9 to your computer and use it in GitHub Desktop.

A service worker for basic offline

// always check for the most current version of Workbox
// https://github.com/GoogleChrome/workbox/releases
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.3/workbox-sw.js');

const OFFLINE_HTML = '/offline/offline.html';
const PRECACHE = [
  { url: OFFLINE_HTML, revision: '70f044fda3e9647a98f084763ae2c32a' }
];

/**
 * Precache Manifest for resources available offline.
 * https://developers.google.com/web/tools/workbox/modules/workbox-precaching#explanation_of_the_precache_list
 */
workbox.precaching.precacheAndRoute(PRECACHE);

/**
 * Enable navigation preload.
 */
workbox.navigationPreload.enable();

/**
 * Enable tracking with Google Analytics while offline.
 * This does not work with other tracking vendors.
 */
// workbox.googleAnalytics.initialize();

/**
 * Basic caching for CSS and JS.
 */
/*
workbox.routing.registerRoute(
  /\.(?:js|css)$/,
  new workbox.strategies.StaleWhileRevalidate({
    cacheName: 'css_js'
  })
);
*/

/**
 * Basic caching for fonts.
 */
/*
workbox.routing.registerRoute(
  /\.(?:woff|woff2|ttf|otf|eot)$/,
  new workbox.strategies.StaleWhileRevalidate({
    cacheName: 'fonts'
  })
);
*/

/**
 * Google Fonts caching
 * Learn more: https://developers.google.com/web/tools/workbox/guides/common-recipes#google_fonts
 */

/**
 * Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
 */
// workbox.routing.registerRoute(
//   /https:\/\/fonts\.googleapis\.com\/*/,
//   new workbox.strategies.StaleWhileRevalidate({ 
//       cacheName: 'google_fonts_stylesheets'
//   }),
//   'GET'
// );

/**
* Cache the underlying font files with a cache-first strategy for 1 year.
*/
// workbox.routing.registerRoute(
//   /https:\/\/fonts\.gstatic\.com\/*/,
//   new workbox.strategies.CacheFirst({ 
//       cacheName: 'google_fonts_webfonts',
//       plugins: [
//           new workbox.cacheableResponse.CacheableResponsePlugin({
//               statuses: [0, 200]
//           }),
//           new workbox.expiration.ExpirationPlugin({
//               maxAgeSeconds: 60 * 60 * 24 * 365, // 1 year
//               maxEntries: 30
//           })
//       ]
//   }),
//   'GET'
// );

/**
 * Basic caching for images.
 */
/*
workbox.routing.registerRoute(
  /\.(?:png|gif|jpg|jpeg|svg|webp)$/,
  new workbox.strategies.StaleWhileRevalidate({
    cacheName: 'images',
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        // Only cache 60 images.
        maxEntries: 60,
        purgeOnQuotaError: true
      })
    ]
  })
);
*/

/*
 * Fallback to offline HTML page when a navigation request fails.
 */
const htmlHandler = new workbox.strategies.NetworkOnly();
// A NavigationRoute matches navigation requests in the browser, i.e. requests for HTML.
const navigationRoute = new workbox.routing.NavigationRoute(({ event }) => {
  const request = event.request;
  return htmlHandler.handle({ event, request }).catch(() => caches.match(OFFLINE_HTML, {
    ignoreSearch: true
  }));
});
workbox.routing.registerRoute(navigationRoute);

Register the Service worker and prevent the default infobar to pop

  <!-- SW CODE START -->
  <link rel="manifest" href="/manifest.json">
  <meta name="theme-color" content="#ffffff">
  <script>
    if ('serviceWorker' in navigator) {
      window.addEventListener('load', function () {
        navigator.serviceWorker.register('/sw.js').then(function (response) {
          console.log('Service Worker registered.');
        }).catch(function (error) {
          console.error(error);
        });
      });

      window.addEventListener('beforeinstallprompt', function (event) { 
        event.preventDefault();
        
        // (optional) Track Add To Home Screen prompt events
        /* event.userChoice.then(choiceResult => {
          ga('send', 'event', 'A2HS', choiceResult.outcome); 
        }); */
      });
    }
  </script>
  <!-- SW CODE END -->

  <!-- (optional) iOS ICONS START -->
  <!-- the first line without sizes attribute is the fallback
         if no size fits; it is also sufficient to add this line
         without the others, as long as the icon is large enough
         (will then be scaled down by the device automatically) -->
  <!--
    <link rel="apple-touch-icon" href="touch-icon-iphone.png">
    <link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad.png">
    <link rel="apple-touch-icon" sizes="180x180" href="touch-icon-iphone-retina.png">
    <link rel="apple-touch-icon" sizes="167x167" href="touch-icon-ipad-retina.png">
    -->
  <!-- (optional) iOS ICONS END -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment