Convert any site to an App – Progressive Web App
Tags: pwa, web, app
Published: 2019-12-14 19:09:46

---
title: Convert any site to an App – Progressive Web App
published: true
description: 
tags: pwa, web, app
---

<div class="entry-content clearfix">

		
<p>According to my opinion – PWA is the future of business applications – those applications that do something with some kind of records and that do not need low level connection to some special hardware, or some not exposed and standardized yet JavaScript API (like contacts, battery level etc). Having your app be web – you are forced to think like – the client could change the code, so you place as much validations as possible on the server. Another thing is – you have full control – over what you publish, when you put out, update, change anything, no policies and restrictions (like in the App Stores) outside of the APIs themselves.</p>



<p>The first requirement of a Web App is to be served over HTTPS. You’ve got to have SSL Certificate from a valid Security Authority. Google is giving more score to HTTPS sites, it flags the address bar of chrome when visiting normal sites as insecure. Hopefully, when you install a certificate, only the users and the server will be able to read their stuff. Why hopefully – I’ve written about it in another post –  <a href="https://tomavelev.com/blog/Internet%20security%20Illusions">https://tomavelev.com/blog/Internet%20security%20Illusions</a> <br>If you don’t have it, with a simple sniffing tool, even some total noob in your local network will be able to get into your communications. With SSL, you have at least the illusion of security from at least the small, not so professional, not-government size threats.<br>If your site is old you could include the following script, so the user get redirected to https:</p>




```javascript
if(location.protocol != 'https:')
 {
  location.href = 'https:' + window.location.href.substring(window.location.protocol.length);
 }
```




<p>Manifest – The manifest is the description of your app, where it is located, some Icons, Colors and other config stuff: </p>



```json
{
  "background_color": "#1b5e20",
  "theme_color": "#1b5e20",
  "description": "Toma Velev's Blog - programming, health, technology, psychology, marketing, philosophy",
  "display": "standalone",
  "icons": [
    {
      "src": "https://tomavelev.com/blog/resources/192.jpg",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "https://tomavelev.com/blog/resources/512.jpg",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "name": "Toma Velev",
  "short_name": "Toma Velev",
  "scope": "/blog/",
  "start_url": "https://tomavelev.com/blog/?source=pwa"
}
```



<p>Some other meta tags about  Icons, Colors  are also required in the HTML:</p>



<pre>
< link rel="apple-touch-icon" href="https://tomavelev.com/blog/resources/192.jpg">
< link rel="manifest" href="fest.json" >
</pre>


<p>Service Worker – Another requirement of a PWA is the site to have registered a Service Worker mainly because of the ability of the service worker to handle requests and access the Indexed DB Storage and the caches even after the browser has cleared the temporary storage and the session has expired.  This gives the developer an option to load some page even if the device is offline and in fresh restart of the browser. Perfectly – the page should be the same as when there is internet, but with some message or some functionality working offline. This depends on the approach. There are two – Server Oriented VS Client Oriented. </p>



<p>If you want to port an old site to PWA with minimal code – generic page should be the go-to. It is Server Oriented. With this the approach the client is just a display. All state is always and only stored on the Server, even if the page has interactivity with AJAX. It probably just replaces HTML sections. </p>



<p>Service Worker opens the possibility all resources – css, js, images to be loaded from the file storage of the client making no network calls and appear like the site is super fast. </p>



```javascript
version = 1;
self.addEventListener('install', function(e) {
 e.waitUntil(
   caches.open('Cache').then(function(cache) {
     return cache.addAll([
        'https://tomavelev.com/blog/resources/192.jpg',

//some more resources to be cached  

        'https://tomavelev.com/blog/resources/js/all.js?' + version,
	   'https://tomavelev.com/blog/resources/css/all.css?' + version,
	   'myIndex.html?'+version,
     ]);
   })
 );
});
self.addEventListener('fetch', function(event) {
  var request = event.request;
  if (request.mode === 'navigate') {
    event.respondWith(
      fetch(request)
        .catch(function() {
          return caches.match('myIndex.html?'+version);
        })
    );
  }
 });
```



<p>The client approach – more popular the recent years, the front end gets a lot of responsibilities – responsiveness, converting the data models to UI, caching domain data and more. This is the way with the native apps, and also with JS front-ends – angular, vue js, react, flutter, etc. Of course not everything is perfect – caching domain info could rise data inconsistencies, the front-end is getting more and more complex every year, and more.  But in terms of data, a web site could be coded to use less bandwidth, it could do some stuff on the client and save more time and bytes and work on the server, etc.</p>



<p>Add to Home screen if your site is close to ready or even ready – PWA – add to home screen should appear when you open it with a modern browser. Without doing anything more (in terms of code).</p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="https://tomavelev.programtom.com/tcdn/resources/pwatomavelev.jpg" alt="" width="180" height="320"></figure></div>



<p>The bad thing about this is, it appears mostly to new users that may or may not know anything about you and as a stranger, getting this popup is annoying – or at least I am when some unknown site asks me to add him to home screen. If you don’t care you will leave it as it. </p>



<p>But if you care here is some code to fix this:</p>



```javascript
let deferredPrompt;
const addBtn = document.querySelector('.add-button');
window.addEventListener('appinstalled', function (e) {
	  console.log('a2hs installed');
	});
window.addEventListener('beforeinstallprompt', function (e) {
	  // Prevent Chrome 67 and earlier from automatically showing the prompt
	  e.preventDefault();
	  // Stash the event so it can be triggered later.
	  deferredPrompt = e;
	  // Update UI to notify the user they can add to home screen
	  addBtn.style.display = 'block';

	  addBtn.addEventListener('click', (e) => {
	    // hide our user interface that shows our A2HS button
	    addBtn.style.display = 'none';
	    // Show the prompt
	    deferredPrompt.prompt();
	    // Wait for the user to respond to the prompt
	    deferredPrompt.userChoice.then((choiceResult) => {
	        if (choiceResult.outcome === 'accepted') {
	          console.log('User accepted the A2HS prompt');
	        } else {
	          console.log('User dismissed the A2HS prompt');
	        }
	        deferredPrompt = null;
	      });
	  });
	});
```


<p>This way, no popup will appear and instead, in place and time where and when it is more appropriate you could ask the user to add your site as home icon/shortcut. <br>P.S. The code that makes this blog to PWA is on the home page - <a href="https://tomavelev.com/blog/">https://tomavelev.com/blog/</a> </p>