DEV Community

Shlok Patel
Shlok Patel

Posted on

react pwa app.

I wanted to create a PWA (progressive web app) with react.js and typescript. So I used a built-in flag with create-react-app which generated pwa.

npx create-react-app my-app --template cra-template-pwa-typescript
Enter fullscreen mode Exit fullscreen mode

But after I ran tests in lighthouse it was not available as a pwa.
So I did some research from web.dev and other sources and built my own template.

  • In src/index.tsx or src/index.js file and change
serviceWorkerRegistration.unregister();
Enter fullscreen mode Exit fullscreen mode

to

serviceWorkerRegistration.register();
Enter fullscreen mode Exit fullscreen mode
  • Add serviceworker.js to pubic/ folder. serviceworker.js works in background and it performs caching, background sync, listen to push notifications and many more stuff!
// public/serviceworker.js
var CACHE_NAME = 'pwatest';
var urlsToCache = [
  '/',
  '/completed'
];

const self = this; 
// 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);
      }
    ).catch(() => caches.match("./offline.html"))
  );
});

// Update a service worker
self.addEventListener('activate', event => {
  var cacheWhitelist = ['pwatest'];
  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
  • Add offline.html to the public directory . This page will render when there is no internet available.
<html>
    <h1>No internet !!!</h1>
</html>
Enter fullscreen mode Exit fullscreen mode
  • Add the script for enabling service workers in body tag of public/index.html
<script>
      if('serviceWorker' in navigator) {
          window.addEventListener('load', () => {
              navigator.serviceWorker.register('./serviceworker.js')
                  .then((reg) => console.log('Success: ', reg.scope))
                  .catch((err) => console.log('Failure: ', err));
          })
      }
</script>
Enter fullscreen mode Exit fullscreen mode
  • Don't forget to add manifest.json
{
  "short_name": "React App",
  "name": "Create React App Sample",
  "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"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}

Enter fullscreen mode Exit fullscreen mode

You have successfully made your current app a react-pwa

To directly use this boilerplate

  • with git
git clone https://github.com/bare-cli/react-pwa-boilerplate.git <your-project-name>
cd <your-project-name>
rm -rf .git
Enter fullscreen mode Exit fullscreen mode
  • with bare Bare is the tool that I have made to generate and manage your boilerplates. Know more about bare here
bare get bare-cli/react-pwa-boilerplate <your-project-name>
Enter fullscreen mode Exit fullscreen mode

Thank you !!
This is my first blog. Please write your reviews in the comments down below.

Top comments (0)