Getting started

Using PWA Fire Bundle

What's in this starter guide?

L P PWA Fire Bundle P Progressive Web App

Hi 👋, here we have the latest features in the PWA Fire Bundle Release [ v 4.0.3 ]

If you have done some pretty cool staff with web apps using basic html and javascript, then you are good to go else, get started with the codelab here.

In your root folder, create two empty files; service-worker.js and app.webmanifest and save. Once done; let's proceed down here;

Register the Service Worker

This is the first step to making your web app work offline. Copy and paste this code to your index file, e.g just before the end of the body tag or in the head tag in html5

N/B : YOU NEED HTTPS : You can only register service workers on Websites, Web Apps or Pages served over HTTPS.

This code checks to see if the Service Worker API is available, and if it is, the Service Worker is registered once the page is loaded.
Check if the browser supports service workers, and if it does, register the Service Worker.

  <!-- register service worker -->
    <script>
    if ('serviceWorker' in navigator) 
        {
          window.addEventListener('load', () => {
          navigator.serviceWorker.register('./service-worker.js')
          .then(() => { console.log("[ PWA Fire Bundle ] Service Worker Registered"); });
        } ); 
      }  
      </script>

Using the Web Manifest

Add a link tag to all the pages that encompass your web app, as follows;


    <!-- start of Web Manifest -->
    <link rel="manifest" href="./app.webmanifest">

Create the Service Worker

NOTE : Rich offline experiences, periodic background syncs, push notifications—functionality that would normally require a native application - are now being built on web. Service workers provide the technical base to which all these features rely on.

A service worker is a script that your browser runs in the background, separate from a web page, opening the door to all amazing PWA capabilities.
Follow the steps as commented in the code below in order to correctly configure the service-worker.js file.
            
  /* after a service worker is installed and the user navigates to a different page or 
  refreshes,the service worker will begin to receive fetch events */  
  self.addEventListener('fetch', (event) => {
    event.respondWith(caches.open('cache').then((cache) => {
      return cache.match(event.request).then((response) => {
        console.log("cache request: " + event.request.url);
         var fetchPromise = fetch(event.request).then((networkResponse) => {           
  // if we got a response from the cache, update the cache                   
  console.log("fetch completed: " + event.request.url, networkResponse);
    if (networkResponse) {
      console.debug("updated cached page: " + event.request.url, networkResponse);
        cache.put(event.request, networkResponse.clone());}
          return networkResponse;
            }, function (event) {   
  // rejected promise - just ignore it, we're offline!   
            console.log("Error in fetch()", event);
            event.waitUntil(
  // our 'cache' here is named *cache* in the caches.open()
            caches.open('cache').then((cache) => { 
            return cache.addAll
            ([            
  // cache.addAll(), takes a list of URLs, then fetches them from 
  // the server and adds the response to the cache          
          './index.html', // cache your index page
          './assets/css/app.main.css', // cache app.main css
          './images/*', // cache all images
          './app.webmanifest',
  // external url fetch, twitter's as an example
          'https://platform.twitter.com/widgets.js', ]); }) 
          ); });
  // respond from the cache, or the network
    return response || fetchPromise;
  }); }));
  });

  // always updating i.e latest version available
  self.addEventListener('install', (event) => {
      self.skipWaiting();
      console.log("Latest version installed!");
  });

Precache using NPM

If you are using node modules for your web application, then we got your back to help you get started. We are going to use workbox. Read more on workbox and latest releases here.

Create an empty js file; service-worker.js in your source root. In the empty source service worker file, say ./src/service-worker.js ; add the following code snippet: Go through the comments.

Checkout for the latest workbox release here and update the importScripts below say 3.6.1 to 4.3.1 if it's available.

  importScripts("https://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js");
      if (workbox) {
          console.log(`Yay! Workbox is loaded ! Cheers to PWA Fire 🐹`);
          workbox.precaching.precacheAndRoute([]);
        } else {
            console.log(`Oops! Workbox didn't load 👺`);
       }
The importScripts call imports the workbox-service-worker.js library from a Content Delivery Network (CDN). Once the library is loaded, the workbox object gives our service worker access to all the Workbox modules.

The precacheAndRoute method of the precaching module takes a precache "manifest" (a list of file URLs with "revision hashes") to cache on service worker installation.

Create an empty sw-config.js file in your project's root folder. Add the code snippet below to it; configure to add which files you want to precache.

                  
       module.exports = {
       "globDirectory": "build/", // The base directory you wish to match globPatterns against, 
       // relative to the current working directory.
       "globPatterns": [
       // edit to add all file to cache; configure for your project below
       "**/*.css", // eg cache all css files, images etc in the root folder
       "index.html",
       "images/*.jpg"
       ],
       "swSrc": "./src/service-worker.js", // The path and filename of the Service Worker file that will be created by the build process.
       "swDest": "build/service-worker.js", // The path to the source service worker file that can contain your own customized code,
       // in addition to containing a match for injectionPointRegexp.
      "globIgnores": [
       "../sw-config.js"
       ]
       };
              
Open your package.json and update the build script to run the Workbox injectManifest command. Add workbox injectManifest sw-config.js infront of your-build-process-task . The updated package.json should look like the following:

    {
      "scripts": 
        {
          "build": "your-build-process-task && workbox injectManifest sw-config.js"
        }
    }

NOTE : workbox-cli ; is a command-line tool that allows us to inject a file manifest into a source service worker file. Add it to your devDependencies as in the code below:


      {
        "devDependencies": {
          "workbox-cli": "^3.0.1"
        }
      }
The precacheAndRoute call in build/service-worker.js has been updated. In your text editor, open build/service-worker.js and observe that your files to cache are included in the file manifest.

Done! Now you will have your production-ready service workers when you build your web app! Let's build! If you get any bug, report it here

OPTIONAL : Want offline analytics for your offline PWA? No problem. Add the code snippet below to ./src/service-worker.js

workbox.googleAnalytics.initialize();

OPTIONAL : Wish you could rely on Google Fonts being available offline after the user has visited your site? Add a quick rule to serve them from the cache.

workbox.routing.registerRoute(
      new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'),
      workbox.strategies.cacheFirst(),
    );
Get started generating your production ready service worker for gulp in this codelab here
Get started generating your production ready service worker for webpack in this codelab here

Workbox Service Worker

This starter code snippet shows how to implement some of the Workbox Strategies so that you objectively cache resources depending on type and need of resources as users interact with your PWA.

workbox-strategies provides the most common caching strategies so it’s easy to apply them in your service worker.
After say, (if need be) using the precache above, you could now define how other resources in your PWA would be served from the cache or internet and in which priority. Your new Service Worker becomes as shown below.

Note : You can choose not to use precache at all and just have your service worker as shown below and use the cache strategies to define how to cache your pwa resources

    /* Using workbox service worker : Docs : https://pwafire.org/developer/pwa/started/#workbox */
    importScripts(
      "https://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js"
    );
    // set debug mode
    workbox.setConfig({
      debug: true
    });
  
    if (workbox) {
        console.log(`[ PWA Fire Bundle 🐹 ] Workbox is loaded`);
        workbox.precaching.precacheAndRoute([]);
    
       /* cache images in the e.g others folder; edit to other folders you got 
       and config in the sw-config.js file */
       workbox.routing.registerRoute(
        /(.*)others(.*)\.(?:png|gif|jpg)/,
        new workbox.strategies.CacheFirst({
          cacheName: 'images',
          plugins: [
            new workbox.expiration.ExpirationPlugin({
              maxEntries: 50,
              maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
            })
          ]
        })
      );
    /* Make your JS and CSS ⚡ fast by returning the assets from the cache, 
    while making sure they are updated in the background for the next use. */
      workbox.routing.registerRoute(
        // cache js, css, scc files 
        /.*\.(?:css|js|scss|)/,
        // use cache but update in the background ASAP
        new workbox.strategies.StaleWhileRevalidate({
          // use a custom cache name
          cacheName: 'assets',
        })
      );

    // cache google fonts
    workbox.routing.registerRoute(
        new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
        new workbox.strategies.CacheFirst({
          cacheName: 'google-fonts',
        })
      );
    // add offline analytics 
    workbox.googleAnalytics.initialize(); 
    /* publish a new service worker and have it update and
    control a web page as soon as possible */
    workbox.core.skipWaiting();
    workbox.core.clientsClaim(); 
    } else {
    console.log(`Oops! Workbox didn't load 👺`);
    }

In the head tag, add theme color to all your pages as shown in the code below; You could use the same theme color as in the app.webmanifest file.


      <!-- theme-color -->
      <meta name="theme-color" content="#fff" />
      <!-- end-theme-color -->

Web Manifest

Configure/edit the background and theme colors, display type, the Web App short name, the Web App name, icons size (keep icon sizes as specified below) and your icon/logo paths. Also state the img type eg image/ico or image/png.

Or maybe you could use our NEW Web Manifest Genarator to genarate the app.webmanifest file. Be among the first to try this tool out! Share out to your comunity.

Leave the start url as recomended though this can be anything you want; the value we’re using has the advantage of being meaningful to Google Analytics.

Configuring the app.webmanifest file helps you to specify how you want your web app to look like when launched on the device.
Configure the app.webmanifest file as directed above in order to fit your web app needs.
 {
          "background_color": "#fff",
          "display": "standalone",
          "orientation":"portrait",
          "theme_color": "#fff",           
          "short_name": "PWA Name",
          "name": "PWA Name",
          "description": "Description or purpose of your PWA",
          "lang": "en-US",
          "icons": [
          {
            "src": "images/icons/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
          },
          {
            "src": "images/icons/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
          }
          ],
          "start_url": "index.html?launcher=true"
          }
  

In the head tag, add theme color to all your pages as shown in the code below; You could use the same theme color as in the app.webmanifest file.


        <!-- theme-color -->
        <meta name="theme-color" content="#fff" />
        <!-- end-theme-color -->

Advanced Recipe

To add more features found in the PWA Fire Bundle, head hands on in our codelabs directory

Add Background Sync to your Progressive Web App, take this codelab asap 😊
Make your Progressive Web App sharable in the native share dialog, take this codelab asap 😊
Install your Native App in your Progressive Web App, take this codelab asap 😊
How to show your users when connected to the internet or not, take this codelab asap 😊

What's next?

Donate a Star like, follow and contribute in any way. Got any bug? Let us know now here. Learn how to use firebase cloud firestore in your realtime progressive web app in this codelab.

License

Licensed under an MIT license.

FORK ON GITHUB