DEV Community

loading...
Cover image for Making React App a Progressive Web App (PWA)

Making React App a Progressive Web App (PWA)

ankitkamboj18 profile image Ankit Kamboj ・3 min read

What is a PWA?

Progressive Web Apps are user experiences that have the reach of the web, and are:

Reliable - Load instantly and never show the down sour, even in uncertain network conditions.
Fast - Respond quickly to user interactions with silky smooth animations and no janky scrolling.
Engaging - Feel like a natural app on the device, with an immersive user experience.

This new level of quality allows Progressive Web Apps to earn a place on the user's home screen.

1. Register a Service Worker

What is a service worker?
Service workers (client-side proxies that pre-cache key resources) enable PWAs to load instantly and provide an instant,
reliable experience for users, regardless of the network state.

Create a new worker.js file in the public folder (public/worker.js) and add the following code:

Let CACHE_NAME = 'your-app-name';
Let urlsToCache = [
  '/',
  '/completed'
];

// Install a service worker
self.addEventListener('install', event => {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

// Cache and return requests
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
        return fetch(event.request);
      }
    )
  );
});

// Update a service worker
self.addEventListener('activate', event => {
  Let cacheWhitelist = ['your-app-name'];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});
Enter fullscreen mode Exit fullscreen mode

Note! from above code replace (your-app-name) with your app name

2. Now Update HTML

Update your index.html file in the public folder (public/index.html)
to check if the client’s browser supports service workers. Just Add below code inside the body tag of your app's (public/index.html)

<script>
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', function() {
          navigator.serviceWorker.register('worker.js').then(function(registration) {
            console.log('Worker registration successful', registration.scope);
          }, function(err) {
            console.log('Worker registration failed', err);
          }).catch(function(err) {
            console.log(err);
          });
        });
      } else {
        console.log('Service Worker is not supported by browser.');
      }
    </script>
Enter fullscreen mode Exit fullscreen mode

3. Activating ServiceWorker

Now go to your app's index.js in the src folder (src/index.js)

Now Update serviceWorker.unregister() to serviceWorker.register() Like Below Code At Last Line

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, 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: http://bit.ly/CRA-PWA
serviceWorker.register();
Enter fullscreen mode Exit fullscreen mode

Restart (npm start) and reload your React app — you should see the message “Worker registration successful” in the console.

4. Create a manifest.json file

Manifest is a simple JSON file that tells the browser about your web application and how it should behave when 'installed' on the user's mobile device or desktop. Having a manifest is required by Chrome to show the Add to Home Screen prompt.

A typical manifest file includes information about the app name, icons it should use, the start_url it should start at when launched, and more.

{
    "name": "your-app-name",
    "short_name": "your-app-name",
    "icons": [
        {
            "src": "img/logo.png",
            "sizes": "92x92",
            "type": "image/png"
        },
        {
            "src": "/img/logo.png",
            "sizes": "144x144",
            "type": "image/png"
        },
        {
            "src": "img/logo.png",
            "sizes": "152x152",
            "type": "image/png"
        }        
    ],
    "start_url": "/",
    "display": "standalone",
    "orientation": "portrait",
    "background_color": "#f0f2f5",
    "theme_color": "#96f2d7"
}
Enter fullscreen mode Exit fullscreen mode

That's it 🎉 Congratulations, you just created a working progressive web app!

Give The heart ❤️ To Appreciate My Work And Follow Me For More Awesome Content.

This Is "Ankit Kamboj"

Check Out React PWA Demo: https://im.ankitkamboj.in/

Discussion (14)

pic
Editor guide
Collapse
morganjay profile image
James Morgan

Don't React apps already come with PWA features?

Collapse
ankitkamboj18 profile image
Ankit Kamboj Author

yes, it used to but now with the latest release, they made it optional.
Now you have to use this additional template if you want yo use service workers and PWA i.e npx create-react-app my-app --template cra-template-pwa

Collapse
mustafaanaskh99 profile image
Mustafa Anas

Any idea why they made it optional?
Does it make the app any "heavier"?

Great tip by the way <3

Thread Thread
ankitkamboj18 profile image
Ankit Kamboj Author

They made it optional because every organization/individual has their own way of implementing service workers and PWA. And they don't want to force something which in the end is not required and replaced by some custom code.
Making the app heavier is not right to say as to when we add our own custom code for service workers and PWA implementation that also takes some memory, so it's not because of making the app heavier. Just they provided choice if we want we can use else skip.

Collapse
morganjay profile image
James Morgan

Thanks!

Collapse
rfinkley profile image
rfinkley

Nice! Thanks for posting.

Collapse
oratexa profile image
Oratexa

@Ankit
Thank you, Nice post!

How can I make a PWA work offline in simple way to access some features & make interactive for weak or no connection?

Collapse
devignacioh profile image
dev-ignacio-h

Nice Demo Ankit!

A couple of doubts, this should work with the latest React template where the PWA is optional?
How do you recommend me to synchronize between a local and a remote database? Indexeddb would be fine? Any advice where to investigate?

Thanks

Collapse
nkirase profile image
Patriotic Nigerian

How do I get the PWA in my system

Collapse
ankitkamboj18 profile image
Ankit Kamboj Author

@Patriotic Nigerian - First you need to decide which tech stack you need to use whether it's Vanilla Javascript with HTML or some framework like React, Angular, Vue, or some other, and based on that you need to configure service workers and manifest.json to make your app a PWA. Service worker part and manifest.json is mandatory for any app to be a PWA. Hope this helps.!!

Collapse
aalphaindia profile image
Pawan Pawar

Thanks for posting.

Collapse
joluga profile image
joluga

How can I cache a WordPress website? Just cache "/" or there is something special about it? I mean a WP with a blog that updates weekly or monthly and updates the web app. Thanks for any help.

Collapse
evalcraciun profile image
Craciun Ciprian

You can use a plugin for wordpress.

Collapse
joluga profile image
joluga

Yes, that would be easy, I seen some plugins, but they mostly do all the work, including the design and I want to avoid that, so the solution would be to design it myself and update every time without having to write every new path in the webapp code. Thanks for answering anyway.