Build modern, offline apps with Progressive Web Apps
Tags: webdev, mobile, pwa
Published: 2020-07-09 21:17:41

Progressive Web Apps (PWAs) could be the next big thing for modern mobile app development. This powerful tool combines the capabilities of a native app and the reach of a web application. They use modern APIs to deliver reliability and installability, while reaching anyone, anywhere, on any device with a single codebase. PWAs are on the rise for web development, and companies large and small are taking advantage of this powerful technology. Today, I want to introduce you to PWAs and get you started with a basic application. 


We will go over:
* [What is a  PWA?](#what-is)
* [Fundamentals of PWAs](#fundamentals)
* [Create a PWA from scratch](#create)
* [What to learn next](#next)
* [Resources](#resources)

<br> 

<a name="what-is"></a>

## What is a PWA?

Progressive Web Apps (PWAs) are web applications that use modern technologies to provide a user experience that closely mimics a native app. PWAs have become very popular in recent years as they do not only improve performance and user experience but are also accessible when a user is offline. 

The primary goal of a PWA is to provide the same experience as a native app using a majority of the features available to mobile app developers. PWAs combine the best of mobile and web apps into one technology. You can essentially build a website using front-end web technologies, but it acts, feels, and behaves like a mobile app. 

<br>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/b81z7ko30e3f5wks2yvj.png)

*Starbucks' modern PWA for offline ordering.*

his modern solution to app development makes it easy for mobile app developers to get their products to market **without going through the slow validation progress** of Apple or Play stores. Once a PWA is deployed, it is **immediately available to users**. This also means that users don't have to manually update apps to get the latest person: it is automatically deployed. 

The development costs for PWAs are notably **cheaper** than native apps, as it eradicates the need for both an iOS and Android team. This valuable modern solution to app development leverages a **larger web ecosystem** for maintaining apps compares to native apps. Progressive Web Apps clearly have a lot of benefits. Let's take a look at some of their characteristics.
* **Progressive:** A PWA must work on every device and enhance progressively, meaning that the features available to a user's device or browser are accounted for.
* **Discoverable:** A progressive web app is essentially a website, so it must be discoverable on search engines. 
* **Offline capabilities:** A PWA should work when the user is offline. It should also work in areas of poor or low connectivity. 
* **App-like:**. PWAs should behave and look like a native app. 
* **Linkable:** PWAs are essentially websites, so they should use the URI to indicate the application's state so that the app can retain its state.

<br>

### Examples of PWAs

Progressive Web Apps are already part of the app ecosystem. You've probably already used one and didn't know it! Here are five popular PWAs to give you a sense of what companies are using this modern technology. 

**Uber:** Uber uses PWA technology for ride-share booking for low-speed, 2G networks. This PWA allows users to access Uber's services on low-end devices that are not compatible with their native app.

**Pinterest:** Pinterest designed a PWA after learning that only 1% of their mobile users convert into sign-ups due to poor mobile performance. They redesigned using PWA-based technology to improve user experience. 

**Starbucks:** Starbucks built a PWA for their web ordering system to provide offline ordering that is similar to their native app.  Starbucks' PWA allows you to browse the menu and customize an order without internet. 

**Spotify:** Spotify is powered by PWA-technology to overcome the limitations of working with Apple. Spotify's PWA app utilized the adaptive UI to changes the background as you progress through the app.

**Soundslice:** Soundslice is a music education software that uses a PWA for their music learning experience. The Soundslice PWA-based player allows users to learn a piece of music while reading it on another mobile or desktop device.

<br>

### Should you build a PWA or native app?

Though there are clearly many advantages to using a PWA, there are still some cases where a native app may be a better decision. Let's break it down a bit further.

**PWAs are ideal the following cases:**
* The app must go to market quickly
* Your budget is limited 
* You have several planned after you go live
* Cross-platform compatibility is a requirement

**Native Apps are ideal for the following cases:**
* Key requirements are speed and responsiveness
* You want to use specific hardware or features
* The app must be integrated with 3rd party applications

<br>

<a name="fundamentals"></a>

## Fundamentals of PWAs

Before we can learn how to download and build PWAs, we need to understand the fundamentals of how these apps are organized and structured. In this section, we'll introduce you to the fundamentals of PWAs. To be successful with this section, you should have some knowledge of HTML, CSS, and JavaScript. Let's get started!

<br>

### Web App Manifest 

The Web Manifest is essential to a PWA. It provides the metadata that *instructs* the browser on how a PWA should be rendered and displayed on any device using a `JSON` text file. It is an important first step and must be installed on the home screen. In a bit, we will show you how to create a Web App Manifest from scratch, but you can also use a manifest generator, which is a common choice for PWA developers. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rt7g2lq4c0ywg32qlwxp.png)

*From Microsoft's PWA documentation*



<br>

### Service workers

Service workers are an important base for all PWAs. They allow us to intercept network requests and implement caching strategies for different calls. Think of this as a kind of web worker, but it is a JavaScript file that acts as a proxy between our web application and our network. It intercepts HTTP requests and serves responses from the network or a local cache. Service workers are secure and cannot interact with the DOM directly. They communicate with pages through the `postMessage` interface, which can directly interact with the DOM. 

<br> 

### PWA File structure    
Take a look at this PWA file structure. We'll discuss the required parts below and explain which features are optional. 

```html
{
  "short_name": "MyCoolPWA",
  "name": "My cool Progressive Web App",
  "orientation": "landscape",
  "description": "A simple experiment with PWAs",
  "background_color": "#3367D6",
  "theme_color": "#3367D6",
  "scope": "/",
  "start_url": "/?source=pwa",
  "display": "standalone",
  "icons": [
    {
      "src": "/images/icons-144.png",
      "type": "image/png",
      "sizes": "144x144",
      "purpose": "maskable any"
    },    
    {
      "src": "/images/icons-192.png",
      "type": "image/png",
      "sizes": "192x192",
      "purpose": "maskable any"
    },
    {
      "src": "/images/icons-512.png",
      "type": "image/png",
      "sizes": "512x512",
      "purpose": "maskable any"
    }
  ],
  "prefer_related_applications": true,
  "related_applications": [
    {
      "platform": "itunes",
      "url": "https://itunes.apple.com/app/native-app/id345"
    },
    {
      "platform": "play",
      "id": "com.my-domain.native"
      "url": "https://play.google.com/store/apps/details?id=com.my-domain.native",
    }
  ],
  "dir": "ltr"
}
```

**`name/short_name`**

This is the value used under the application icon once your PWA is installed on a user device. `short_name` is used if when there's not enough available space. I recommend keeping it under twelve characters to avoids truncation. 

**`start_url`**

This is the path to your app assets to be loaded when your PWA is launched. This will indicate that we want the app to start on the home page every time it is launched. 

**`display`**

This specifies how your PWA app will be displayed, and you can specify different values depending on browser experiences, such as `browser` for a standard experience or `standalone` for independent windows.  

**`icons`**

This will determine which icons are on the home screen or splash screen. It should be at least *144px* resolution. Some browsers, like Chrome, suggest having two icons of different sizing to help with scaling on different devices. We can then use the `purpose` attribute to indicate the purpose of those different icons.

**`background_color`**

As the name indicates, this will set the PWAs background color. You can determine which color you want, and on Chrome, that background color is also used for the splash screen. 

The following features in our PWA file structure are **optional properties** for adding different functionalities or design elements. They are recommended if you want a fully-developed PWA, but if you just want to start with the basics, you only need what we discussed above.

* `orientation`
* `theme_color`
* `scope`
* `description`
* `related_applications`
* `dir`


> ## Master Progressive Web Apps. 
Learn how to build, deploy, and host PWAs without scrubbing through videos or complex documentation. Master all the necessary tools to become a proficient PWA developer. Educative's text-based courses are easy to skim and feature live coding environments, making learning quick and efficient. 
> 
> <b>[Zero to Hero with Progressive Web Apps
](https://www.educative.io/courses/zero-to-hero-with-progressive-web-apps)</b>

<br>

<br>

<a name="create"></a>

## Create a PWA from scratch

Now that we are familiar with the fundamentals of PWAs, let's learn how to make one from scratch! This guide will introduce you to the basics of creating a PWA. *For a more robust guide to building a PWA, check out Educative's course [Zero to Hero with Progressive Web Apps](https://www.educative.io/courses/zero-to-hero-with-progressive-web-apps).*  

<br>

### Step 1: Build a basic website

To make a PWA, we need a website. You can either make one from scratch, so long as it scales well on different screens, browsers, and devices, or you can download a template. If you use a template, replace the content in the `index.html` and change the colors or design using CSS. Once we have our site, we can turn it into a Progressive Web App. 

<br>

### Step 2: Make an app icon for your home screen 

As we mentioned in the File Structure section, you'll need an app icon for your PWA. This will be on the home screen. You can either make your own logo or download free ones from online sources. Either way, your logo needs to be a square and should be at least *144px* resolution. Once you make the icon, download it and add the HTML code to the `<head>` of the `index.html` file. Be sure to check that the path to this file is correct. For Apply devices, there are some extra required settings for displaying PWA icons properly. 


<br>

### Step 3: Create and register the Web App Manifest

As I mentioned before, the Web App Manifest is an important step for making a PWA. This is the file that contains all your website's data. You can either make one from scratch or use a Webb App Manifest Generator and fill in the data you want. This is a good option if you're just starting out, as you can leave default settings for the features you don't understand. 

Typically, the manifest file is stored at the root of our web application. It can be named anything you want so long as it has `.webmanifest` at the end. Then, we serve it with the media type `application/manifest+json`. We then have to associate a manifest to a web application using the `<link>` tag in the `<head>` section of our HTML document. Here's an example that indicates to the user agent that the manifest metadata must be adopted. We also need to add credentials by adding the attribute `crossorigin="use-credentials`.

```html
<head>
  <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials">
</head>
```

<br>

### Step 4: Add a service worker 

As I outlined before, a service worker acts as the proxy for our application and network. It is another file we need to add to our PWA so it will work offline. To succeed at creating service workers, you need some knowledge of [promises in JavaScript](https://www.educative.io/blog/javascript-promises-tutorial). To create a service worker, there are four main steps:

**1. Register the service worker using the JavaScript file that contains the logic of our service worker.** You can use the following code. During this phase, you may generate an `error` if the service worker file cannot be fetched. 

```js
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/serviceWorker.js')
      .then((registration) => { 
         // The registration was successful       
      })
      .catch((err) => {
         // The registration failed
      });
  } 
```

<br>

**2. Install your service worker.** In this phase, pre-fetch operations are typically executed to ensure that target assets (such as static files) are downloaded. this is where we use *promises* in our JavaScript code. Both `caches.open()` and `cache.addAll()` will return promises. After it is installed, the service worker will delay activation until an older service worker is no longer controlling clients (if you already had one installed). 

```js
var urlsToCache = [
  '/',
  '/styles/styles.css',
  '/script/home.js'
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('my-cache')
      .then((cache) => {
        return cache.addAll(urlsToCache);
      })
  );
});
```

<br>

**3. Activating the service worker.** Once the old service worker is gone, and the new one will be activated. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yyp8sxvmfl7v6w6j4y0c.png)
*From Google's PWA documentation*

<br>

**4. Fetch and intercept requests.** Now our service worker is installed and activated, so it can intercept requests and communicate with the local cache. There are several ways we can implement this stage. For now, I'll show you the easiest approach for a general PWA scenario. 

```js
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        // The responce is in the cache
        if (response) {
          return response;
        }

        // No cache match, we attempt to fetch it from the network
        return fetch(event.request);
      }
    )
  );
});
```


Now we understand the basic steps behind creating and installing a service worker to our PWA. Keep in mind that there are other ways to approach service workers, such as using the `sw-toolbox` or leveraging different caching strategies. If you want more hands-on practice with service workers and their life cycles, Educative's course [Zero to Hero with progressive Web Apps](https://www.educative.io/courses/zero-to-hero-with-progressive-web-apps) teaches you how to create custom offline pages. Now let's move on to the next stage of creating a PWA.
 
<br>

### Step 5: Initialize an Add to Home Screen Dialog

An Add to Home Screen Dialog (A2HS) is how a user will install the application locally on their device. We also need to serve the app through an HTTPS connection. To do so, Chrome will require your PWA to have a registered service worker. Once the requirements are fulfilled, the browser will display the A2HS dialog, such as a button, pop up, or menu option. Once it is added to the home screen, your PWA will look like a native app using the icon you provided.

<br>

### Step 6: Test your PWA and Manifest File

Now that you have your basic PWA, you'll want to test to see if it is working and determine if it's a good PWA. A common tool for PWA developers is Google Lighthouse, which will assess your PWA and make suggestions on how to improve it. You can install Lighthouse, open your website, and click Generate Report. This will open a tab with valuable information. The data you should focus on is the rating for the categories Progressive Web App, Performance, Accessibility, and Best Practices. From there, you can determine what changes should be made. 

You'll also want to test the manifest file. To do so, you can use your browser's DevTools. In Chrome, for example, you'll want to open the Application tab, access the Manifest section (on the left), and see the properties of our file. It will display warnings if there are errors. You can also use a manifest validator for this step. 
 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tlil1k5226yxf4tccg2y.png)

<br>

<a name="next"></a>

## What to learn next 

*Congrats!* You now know to create a basic PWA and download it to a user's home screen. Clearly, this process is a lot faster and easier than the traditional native app process. PWAs are a powerful tool for modern web app creation and deployment. There is still a lot to learn to master PWA development. The next things and tools you'll need to learn are:
* Caching strategies 
* Cloud Firestore for offline persistence 
* PWA libraries and Workbox
* How to create a PWA with Angular 
* Deploying and hosting a PWA 

Educative's course [Zero to Hero with Progressive Web Apps](https://www.educative.io/courses/zero-to-hero-with-progressive-web-apps), written by senior software engineer and PWA enthusiast Francesco Leardini, will take you through all these steps and more with hands-on practice. This course teaches you in-depth strategies for building services workers, caching, deploying PWAs via Firebase, and more. By the end, you'll be a confident PWA developer with a functioning progressive app.

Take charge of your career and learn how to create modern progressive web apps. 

<br>

<a name="resources"></a>

## Keep reading  
* [A quick dive into Firebase: jumpstart your full-stack journey
](https://www.educative.io/blog/a-quick-dive-into-firebase)
* [JavaScript Promises Tutorial: how to write asynchronous code](https://www.educative.io/blog/javascript-promises-tutorial)
* [The Roadmap to becoming a Front-End Developer](https://www.educative.io/blog/roadmap-to-become-a-front-end-developer)
* [Android Tutorial: How to Develop an Android App
](https://www.educative.io/blog/how-to-develop-an-android-app)