Progressive Web App (PWA) using React

Develop a progressive web application using React.

Progressive Web Application

Overview

In this article, let’s develop a progressive web application using React.

From Wikipedia,

A progressive web application (PWA) is a type of application software delivered through the web, built using common web technologies including HTML, CSS and JavaScript. It is intended to work on any platform that uses a standards-compliant browser, including both desktop and mobile devices.

Setup

Let’ start by creating a progressive web application using create-react-app and the PWA template.

npx create-react-app react-pwa-app --template cra-template-pwa

I use the Javascript template. For Typescript, use cra-template-pwa-typescript.

I am going to leverage the sample code I developed in my previous article to display a dynamic grid with user details and dropdowns of countries and cities.

The sample application shall look like below. You can find the code in this repository.

Sample React App.

Benchmark

Now let’s benchmark the application for PWA. I am going to build the application and serve the build.

yarn build
yarn global add serve
serve -s build
Build and Serve App

Using Google Chrome or Brave browser, navigate to http://localhost:5000and open the Developer Tools. I am going to use LightHouse to generate a report.

Google Lighthouse
PWA Report

The application is not yet PWA ready. Let’s change it.

Service Worker

A service worker enables offline work for web applications. If you open package.json you can see a list of workbox libraries configured as part of the PWA template.

Workbox is a set of libraries that can power a production-ready service worker for your Progressive Web App.

{
"name": "react-pwa-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"ag-grid-community": "^25.1.0",
"ag-grid-react": "^25.1.0",
"faker": "^5.5.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"web-vitals": "^0.2.4",
"workbox-background-sync": "^5.1.3",
"workbox-broadcast-update": "^5.1.3",
"workbox-cacheable-response": "^5.1.3",
"workbox-core": "^5.1.3",
"workbox-expiration": "^5.1.3",
"workbox-google-analytics": "^5.1.3",
"workbox-navigation-preload": "^5.1.3",
"workbox-precaching": "^5.1.3",
"workbox-range-requests": "^5.1.3",
"workbox-routing": "^5.1.3",
"workbox-strategies": "^5.1.3",
"workbox-streams": "^5.1.3"

},

To enable the service worker, open index.js and register the service worker.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://cra.link/PWA
serviceWorkerRegistration.register();
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Maskable Icon

Maskable icons is a new icon format that ensures that your PWA icon looks great on all Android devices. On newer Android devices, PWA icons that don’t follow the maskable icon format are given a white background. When you use a maskable icon, it ensures that the icon takes up all of the space that Android provides for it.

Open manifest.json and add the maskable icon. I did not create a custom icon for the app. You can use the Maskable.app Editor to create one for your app.

{
"short_name": "React PWA",
"name": "React Progress Web Application",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
},
{
"src": "logo192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
}

],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

Benchmark

Now build and benchmark the application again and it should be PWA ready.

PWA Report

Hosting

To make it simple, I am going to serve the application using GitHub pages. I will also enforce HTTPS as this is part of PWA requirements.

Make the following changes in package.json.

"homepage": "https://alpha2phi.github.io/javascript-apps",
...
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"predeploy": "yarn build",
"deploy": "gh-pages -d build"

},

Now run

yarn add gh-pages
yarn run deploy
Deployment to GitHub Pages
Hosting using GitHub Pages

You can access the application here.

PWA using GitHub Pages

The application is installable now.

Installable PWA

And here is the PWA report for the hosted application.

PWA Report

You can try turning off Internet access and the application should still be accessible.

Summary

Developing a progressive web application using React is easy. Looking at the advantages it brings, developers should explore and consider if PWA is the right fit for their applications.

References

Programmer and occasional blogger.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store