DEV Community

Shlok Patel
Shlok Patel

Posted on

7 3

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)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay