react pwa app.
Tags: react, pwa, typescript, javascript
Published: 2021-10-02 22:29:02

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. 
```sh
npx create-react-app my-app --template cra-template-pwa-typescript
```
But after I ran tests in lighthouse it was not available as a pwa.
So I did some research from [web.dev](https://web.dev/progressive-web-apps/) and other sources and built my own template.

- In `src/index.tsx` or `src/index.js` file and change 
```js
serviceWorkerRegistration.unregister();
```
to
```js
serviceWorkerRegistration.register();
```
- 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!
```js
// 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);
          }
        })
      );
    })
  );
});
```
- Add `offline.html` to the `public` directory  . This page will render when there is no internet available.
```html
<html>
    <h1>No internet !!!</h1>
</html>
```
- Add the script for enabling service workers in `body` tag of `public/index.html`
```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>
```
- Don't forget to add manifest.json
```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"
}

``` 

### You have successfully made your current app a react-pwa

### To directly use this boilerplate
- with git
```sh
git clone https://github.com/bare-cli/react-pwa-boilerplate.git <your-project-name>
cd <your-project-name>
rm -rf .git
```
- with bare<br/>
Bare is the tool that I have made to generate and manage your boilerplates. Know more about bare [here](https://bare.surge.sh)
```sh
bare get bare-cli/react-pwa-boilerplate <your-project-name>
```
Thank you !!
This is my first blog. Please write your reviews in the comments down below.