You have developed your Asp.Net Core MVC, it’s working fine and then you want to take it into the next level: to make it installable and allow it to be distributed in the platform store. But a web app is a web app and, as so, it should run in the browser. That would be true some years ago, but not anymore.
There are several ways to transform your web app into an installable app, without rewriting it. One easy way to do it is to transform it into a Progressive Web App (PWA). A PWA is an app that allows to be installed in the hosting OS, is multiplatform, and doesn’t need the browser to be ran. That seems too good to be true, but there is more: it can also use the resources of the hosting OS, as a native app and can be sent and distributed in the platform store.
That seems very nice, no ? And what are the requirements to make a PWA ?
- It should be launchable and installable
- It should be fast, even on slow networks
- It should serve data using HTTPS, not HTTP
- It should offer offline experience
- It should run in all browsers
- It should have responsive design
The full checklist for a PWA can be found here. There is a resource to audit your app, it’s called Lighthouse and can be accessed by opening the Dev Tools (F12):
If you click on Generate report, it will scan your website to see if you have everything to run your app as a PWA:
Ok. Now we know how to check if our website is ready for being a PWA, but what does it take to transform it into a PWA? Basically, two things: a Service Worker and a manifest file.
The Service worker is a script that runs separately from your web page and offers extra functionality, like push notifications and background sync. You can read more about it here.
The app manifest is a json file that will add metadata information for your app. in a way that it can be used to install the app. Sound simple, no ? Well, it’s not that difficult, we’ll do it right now.
The first step is to create a service worker, we’ll use the tutorial described in https://developers.google.com/web/tools/workbox/guides/get-started. Let’s create a file named serviceWorker.js and add it to the wwwroot folder:
console.log('Hello from serviceWorker.js');
Then, we’ll register it in the end of the _Layout.cshtml file:
<script> // Check that service workers are supported if ('serviceWorker' in navigator) { // Use the window load event to keep the page load performant window.addEventListener('load', () => { navigator.serviceWorker.register('/serviceWorker.js'); }); } </script>
Once you do that, you can open the dev tools and, in the console, you will see the message:
You can also check in the Application tab, under Service Workers, that it’s up and running:
This works, but it’s not very useful. You can create your own service worker by using Workbox, a tool developed by Google, to develop something that matches your needs. For now, we’ll use workbox cli to generate the service worker (for that, you will have to have npm installed in your machine). Install the workbox cli with:
npm install workbox-cli --global
Then run the wizard, to generate a configuration file:
workbox wizard
Once the wizard has ran, you can generate the service worker with:
workbox generateSW workbox-config.js
That will generate a sw.js file in wwwroot. You have to change the register procedure in _Layout.cshtml to reflect this change:
<script> // Check that service workers are supported if ('serviceWorker' in navigator) { // Use the window load event to keep the page load performant window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js'); }); } </script>
Once you do that, the next step is to add a manifest file to your app. The easiest way to do it is to use a manifest generator, like this one:
You will need an icon for the app. I went to https://freeicons.io and downloaded an image for my icon and added it to the manifest generator. Then I downloaded a zip with the manifest file and the icons for the app. The manifest file is something like this:
{ "theme_color": "#3558f6", "background_color": "#2a10b1", "display": "standalone", "scope": "/", "start_url": "/", "name": "MyMVCApp", "short_name": "mymvcapp", "description": "Sample MVC PWA app", "icons": [ { "src": "/images/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/images/icon-256x256.png", "sizes": "256x256", "type": "image/png" }, { "src": "/images/icon-384x384.png", "sizes": "384x384", "type": "image/png" }, { "src": "/images/icon-512x512.png", "sizes": "512x512", "type": "image/png" } ] }
This manifest file must be put on the wwwroot folder of the app with the name of manifest.json and the images, on wwwroot/images folder.
Your PWA is ready. You can run it and see if it’s installable, by checking if this icon is present in Edge (there should be a similar one in the other browsers):
Clicking on it, you will have an install prompt:
If you choose to install it, you will have an app that will run in a window, will have an icon (which you can pin in the taskbar in Windows) and an icon in the start menu:
This app is multi-platform, meaning that you can install it on Linux, Mac or any phone platform. If you press F12 to open the Dev Tools, they will open and then, in the Application tab, you can see the manifest data:
We can check the app in Lighthouse for the PWA compatibility:
From it, you can see three errors
- Redirects HTTP traffic to HTTPS Error!
- Does not provide a valid
apple-touch-icon
- Manifest doesn’t have a maskable icon