Skip to content

Instantly share code, notes, and snippets.

@Antoinebr
Last active January 7, 2020 19:58
Show Gist options
  • Save Antoinebr/de670e61d80c4121d45b53de1ac07b4a to your computer and use it in GitHub Desktop.
Save Antoinebr/de670e61d80c4121d45b53de1ac07b4a to your computer and use it in GitHub Desktop.
pwa-event-paris

Install workbox

npm install workbox-cli.

List your assets that will only change at build time

// workbox-config.js 

module.exports = {
    globDirectory: './',
    globPatterns: [
      'img/logo*.png',
      '{js,css}/*.{js,css}'
    ],

    swDest: './sw.js',
    clientsClaim: true,
    skipWaiting: true
  };

Generate the precache

workbox generateSW

Add custom logic


/*
| --------------------------------------------------------------------------
| Caching the home page 
| --------------------------------------------------------------------------
*/

workbox.routing.registerRoute( "/" , (args) => {

  return workbox.strategies.networkFirst()
        .handle(args).then((response) => (!response) ? caches.match('/offline.php') : response);

});



workbox.routing.registerRoute( '/index.php', (args) => {

  return workbox.strategies.networkFirst()
        .handle(args).then((response) => (!response) ? caches.match('/offline.php') : response);

});


/*
| --------------------------------------------------------------------------
|  Caching of the listing
| -------------------------------------------------------------------------- 
*/ 
const productsNetworkFirstHandler = workbox.strategies.networkFirst({
  cacheName: 'list',
  
  plugins: [
    new workbox.expiration.Plugin({
      maxEntries: 30,
      maxAgeSeconds: 2 * 30 * 24 * 60 * 60,
    }),
    new workbox.cacheableResponse.Plugin({
      statuses: [200]
    }),

  ]

});
  
    
workbox.routing.registerRoute(/list.php/, (args) => {

  return productsNetworkFirstHandler.handle(args).then((response) => (!response) ? caches.match('/offline.php') : response);

});
  


/*
| --------------------------------------------------------------------------
|  Caching the details
| -------------------------------------------------------------------------- 
*/ 

const catsNetworkFirstHandler = workbox.strategies.networkFirst({
  cacheName: 'detail-page',
  
  plugins: [
    new workbox.expiration.Plugin({
      maxEntries: 10,
      maxAgeSeconds: 2 * 30 * 24 * 60 * 60,
    }),
    new workbox.cacheableResponse.Plugin({
      statuses: [200]
    }),

  ]

});
  
    
workbox.routing.registerRoute(/detail-page.php/, (args) => {

  return catsNetworkFirstHandler.handle(args).then((response) => (!response) ? caches.match('/offline.php') : response);

});

Register the service worker

<script>
        if ("serviceWorker" in navigator) {
          navigator.serviceWorker.register("./sw.js").then(function(registration){
          
            console.log("Service Worker registered with scope:", registration.scope );
        
          }).catch(function(err) {
            
            console.log("Service worker registration failed:", err);
        
          });
        
        }
</script>

Onesignal

Install the SDK

<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
<script>
  var OneSignal = window.OneSignal || [];
  OneSignal.push(function() {
    OneSignal.init({
      appId: "26e25b26-86b2-4234-bd44-3b7f9365c735", // replace your id 
      autoRegister: false,
      notifyButton: {
        enable: false,
      },
    });
  });
</script>

Next, you'll need to add the OneSignal SDK files to your site. To do so,

Download the files here Unzip the OneSignal SDK files. There should be three files:

Upload the OneSignal SDK files to the top-level root of your site directory, making them publicly accessible.

A custom notification button

<a href="#" id="subscribe-link" style="display: none;">Subscribe to Notifications</a>

    <script>
        function subscribe() {
            OneSignal.push(["registerForPushNotifications"]);
            event.preventDefault();
        }

        var OneSignal = OneSignal || [];
        /* This example assumes you've already initialized OneSignal */
        OneSignal.push(function() {
            // If we're on an unsupported browser, do nothing
            if (!OneSignal.isPushNotificationsSupported()) return;
            OneSignal.isPushNotificationsEnabled(function(isEnabled) {
              
                if (isEnabled) {
                    // The user is subscribed to notifications
                    // Don't show anything
                } else {
                    document.getElementById("subscribe-link").addEventListener('click', subscribe);
                    document.getElementById("subscribe-link").style.display = '';
                }
            });
        });
    </script>
    

Basic offline page

The service worker

// sw.js 


/*
| --------------------------------------------------------------------------
|  Fetch return a promise : so we can catch if something goes wrong
| --------------------------------------------------------------------------
|  
|  In this example : if the request can't be made we reply with a text response
| 
*/

var responseContent = 
`
<!DOCTYPE html>
<html class="no-js">
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title></title>
	<meta name="description" content="">
	<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
    <body>
        <style>
          
          body{
            background-color: #292929;
            font-family : sans-serif;
            text-align: center;
            color: #d4d4d4;
          }
          
           img{
               display:block;
               margin:auto;
           }
          
          a{
            display:block;
            margin:auto;
            width: 200px;
            max-width: 100%;
            background-color: #FFF;
            height : 40px; 
            line-height: 40px;
            color: black;
            text-decoration:none;
            
            margin-top: 30px; 
          }
          
        </style>
        <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAABTCAYAAABwOo6iAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MzkzRTU3QzZFMkY0MTFFNDhBMDg4NTZGQjEyQjlFOTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzkzRTU3QzdFMkY0MTFFNDhBMDg4NTZGQjEyQjlFOTYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozOTNFNTdDNEUyRjQxMUU0OEEwODg1NkZCMTJCOUU5NiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozOTNFNTdDNUUyRjQxMUU0OEEwODg1NkZCMTJCOUU5NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PlAVwfIAAA4pSURBVHja7F0JkBXF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" style="">
        
        <h1>Your seems to be offline :x </h1>
       
        <p>A question ? Send us an email ...</p>
      
        <a href="mailto:[email protected]"> send an email </a>
    </body>
</html>
`;


self.addEventListener("fetch", function(event) {

    event.respondWith(
        fetch(event.request).catch(function() {
            return new Response(responseContent, { headers: { "Content-Type": "text/html; charset=utf-8" }}
            );
        })
    );

});

Register the service worker

<script>
        if ("serviceWorker" in navigator) {
          navigator.serviceWorker.register("./sw.js").then(function(registration){
          
            console.log("Service Worker registered with scope:", registration.scope );
        
          }).catch(function(err) {
            
            console.log("Service worker registration failed:", err);
        
          });
        
        }
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment