How to Convert an Umbraco Website to a PWA or Progressive Web App

Stephen Garside | Sun 28 Jun 20 > 5 min read

A Progressive Web App or PWA is a great way to serve website content to users in a fast, app like experience, even if they are offline. Here is how to create or convert an Umbraco website to a progressive web app in 5 easy steps:

  1. Create icon image files to launch your progressive web app on user devices and add these to your website images directory.
  2. Add a json manifest file to the root of your website to provide configuration details for your PWA including a name, description and icon urls.
  3. Add a JavaScript Service Worker file to the root of your website.
  4. Register your Service Worker by adding basic JavaScript code to your website template page.
  5. Add an offline page to your website for use by the PWA when certain content is unavailable.

Any simple website including those created with Umbraco, Wordpress, Sitecore or Kentico can be converted to a progressive web app or PWA using this approach.

 

Progressive Web Apps Pwa For Umbraco
How A Simple Umbraco Progressive Web App Works

How does an Umbraco PWA Work?

Before explaining how to convert a simple website into a Progressive Web App, it helps to understand how a PWA works. A picture speaks a thousand words, so this image helps explain things. In simple terms:

  • User visits your website and is prompted to install your PWA.
  • User accepts, and a JavaScript Service Worker is installed on their device.
  • Subsequent GET requests to your website are routed (proxied) via the Service Worker.
  • Service Worker provides previously retrieved content from local device cache where appropriate or if user is offline.

There is a lot more to Progressive Web Apps than outlined above, and for more complex PWAs I recommend reading the excellent PWA tutorials provided by Google and Mozilla.

How To Create an Umbraco Progressive Web App

Step 1 - Create Icon Files

Progressive web apps can be launched from an icon on your users device or desktop, for example:

Icons should be created in the following sizes to ensure the most appropriate one is available for the user's device - I tend to use .png format. Your icon files should be saved in an /images/icons directory in the root of your Umbraco PWA website.

Android
icon-72x72
icon-96x96
icon-128x128
icon-144x144
icon-152x152
icon-192x192
icon-384x384
icon-512x512

IOS
icon-120x120
icon-180x180

Depending on device, your icon maybe masked (i.e. rounded edges applied or cropped to a circle).  To see how your icon might appear across devices I recommend reading this article on maskable icons , and this online app for generating maskable icons.  You can also utilise Chrome dev tools > Application > Manifest for a view of how your icons will look should they be masked.

You should add the following link tag to your website master / template page in the <head> section to identify the 192x192 icon file as the apple touch icon:

<link rel="apple-touch-icon" href="~/images/icons/icon-192x192.png">

Step 2 - Add a Manifest File to Website Root Folder

The next step to convert your Umbraco website to a PWA is to add a manifest.json file to the root  (top level) folder of your website.  This file is basically a set of instructions for the device on how to theme your PWA. 

Here is a boiler plate manifest.json file you can amend as required and I recommend the following article for a more detailed description of the options within a manifest file.

Once you have created your manifest file, add a link tag to the <head> section of all your website pages, a master / layout page is a good place to do this:

<link rel="manifest" href="/manifest.json">

 

Invalid Json in PWA Manifest Response Body 

A word of caution about your manifest file - you may experience issues converting your PWA to an Android .apk, especially if you use Bubblewrap. I consistently experienced the following error whilst trying to convert my PWA to an .apk:

ERROR invalid json response body at https://www.stephengarside.co.uk/manifest.json reason: Unexpected token  in JSON at position 0

The fix was to ensure my manifest.json (or manifest.webmanifest) was UTF-8 encoded. The simplest way to do this is download notepad++ and re-save your file in UTF-8 format.

{
  "name": "Your Progressive Web App Name",
  "short_name": "Short App Name",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#000",
  "theme_color": "#000",
  "description": "Description of your Progressive Web App",
  "display": "standalone",
  "orientation": "any",
  "lang": "English",
  "scope": "/",
  "icons": [
    {
      "src": "images/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "images/icons/other-icon-files.png",
      "sizes": "sizeXsize",
      "type": "image/png",
      "purpose": "any maskable"
    },
  ],
  "screenshots": [
    {
      "src": "images/screenshots/screenshot1.jpg",
      "sizes": "1280x720",
      "type": "image/jpg"
    },
    {
      "src": "images/screenshots/screenshot2.jpg",
      "sizes": "1280x720",
      "type": "image/jpg"
    }
  ]
}

Step 3 - Add a Javascript Service Worker

At the heart of an Umbraco progressive web app is something called a Javascript Service Worker, which is a bit of code that acts as a proxy between the app and your website. Amongst other things, this service worker can be configured to use a local store on the device (known as a cache) to save and serve your website content when the user is offline, or when they have a slow connection speed. 

For simple websites I recommend using a generic PWA javascript service worker such as this one by Mads Kristian which you can download from his GitHub site.  I had to make a few minor tweaks for my use case, and you can get the version I use for Umbraco here.

Add this file to the root folder of your website and rename it serviceworker.js .

Step 4 - Add CODE to Register Service Worker

The next step is to add the following JavaScript to your Umbraco website template / master page (wrapped in <script> tags). If a user agrees to install your progressive web app, this code will download and register the service worker on the device:

if ('serviceWorker' in navigator) {
    // Use the window load event to keep the page load performant
    window.addEventListener('load', () => {
        navigator.serviceWorker.register('/serviceworker.js').then(function () {
            console.log('service worker installed');
        }, function () {
            console.log('error installing service worker');
        });
    });
}

Step 5 - Create an Offline Page

The final step is to create an 'Offline' page that your PWA will display to the user if they are currently offline and they have not previously browsed a particular page of your web app. If you are using the boilerplate javascript service worker mentioned above then your offline page url should be /offline.html.

Test Your PWA with Google Lighthouse

I like to test that I have implemented a progressive web application into an Umbraco website correctly by conducting a test using Google Lighthouse. Simply open Lighthouse and kick off a test for the home page of your app.  Once the test completes you are looking for a 100% score:

Progressive Web App Test Results In Google Lighthouse

And thats all there is to creating or converting an Umbraco website to a progressive web app. Don't forget, these instructions will also work for how to create progressive web apps for Kentico, Sitecore and Wordpress.

There's a whole lot more to progressive web apps than outlined in this article. For larger, more complex websites I recommend looking at Workbox from Google, which is a set of javascript libraries for building service workers for progressive web apps. Workbox gives you the ability to select more granular caching strategies for different elements of your PWA, plus has good integration with front end build tools such as Webpack. 

If you have any questions about this article or your want to discuss your progressive web app project requirements please get in touch.

Leave Your Comments...