CRA to PWA 😎

Manal Liaquat
The Startup
Published in
4 min readAug 15, 2020

This is the most searched topic on the internet today, “How to convert CRA (Create React App) to PWA (Progressive Web App)”.

To convert any website into PWA you’ve to add to files:

  1. manifest.json
  2. service-worker.js
CRA to PWA

CRA already has a basic service worker file for registering the service worker, just open ./src/index.js file and call the method serviceWorker.register(); or replace unregister() to register()

This will cache all the static files and assets and make the website work offline. CRA has a very little configuration of PWA to work on any smartphone and it doesn’t have an install popup configuration. So registering the service worker doesn’t make the app install on a smartphone. We need to configure it by ourselves.

STEPS

  1. Make the web app installable
  2. Add Windows and iPhone supported tags
  3. Configure the service worker to cache network images too, not only static images.

Step 1/3:

We need to edit manifest.json file, open ./public/manifest.json file and replace it with

{"short_name": "My App", // this will show on homescreen icon"name": "My App","icons": [{"src":"icon-192x192.png", // make sure icons must have appropriate sizes and path - my icon is in ./public/icon-192x192.png"sizes": "192x192","type": "image/png"},{"src":"icon.png","sizes": "512x512","type": "image/png"}],"orientation": "portrait","start_url": "/","background_color": "#222", // splash screen background color"theme_color": "#222", // notification panel color"display": "standalone"}

Step 2/3:

Windows and iPhone doesn’t fully support PWAs with basic configuration, so we need to add “meta-tags” for to make app work in Windows phone and iPhone. Add the given below meta tags in ./public/index.html head section.

In CRA, /public/index.html, parent path represents “%PUBLIC_URL%” so it must be included with every static file, image or icon otherwise none of the assets will import.

For All Phones:

<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />

For Windows Phone:

<meta name="mobile-web-app-capable" content="yes"><meta name="theme-color" content="#536878"><meta name="msapplication-navbutton-color" content="orange"><meta name="msapplication-TileColor" content="orange"><meta name="msapplication-TileImage" content="%PUBLIC_URL%/icon/icon-144x144.png"><meta name="application-name" content="My App"><meta name="msapplication-tooltip" content="My App Description"><meta name="msapplication-starturl" content="%PUBLIC_URL%/menu?utm_source=homescreen"><meta name="screen-orientation" content="portrait">

For iPhones:

<meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-title" content="My App"><link rel="apple-touch-icon" href="%PUBLIC_URL%/icon.png"><link rel="apple-touch-icon" sizes="152x152" href="%PUBLIC_URL%/icon/icon-192x192.png"><link rel="apple-touch-icon" sizes="180x180" href="%PUBLIC_URL%/icon/icon-192x192.png"><link rel="apple-touch-icon" sizes="167x167" href="%PUBLIC_URL%/icon/icon-192x192.png">

Safari browser doesn’t show splash screen so we need to make custom splash screens for each size of iPhone then add these meta tags for safari browser.

<link href="%PUBLIC_URL%/icon/splashscreens/iphone5_splash.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/iphone6_splash.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/iphoneplus_splash.png" media="(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/iphonex_splash.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/iphonexr_splash.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/iphonexsmax_splash.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/ipad_splash.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/ipadpro1_splash.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/ipadpro3_splash.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /><link href="%PUBLIC_URL%/icon/splashscreens/ipadpro2_splash.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />

Step 3/3:

One of the most asked question is how to cache network images in CRA, so this is the part we cover this problem.

CRA uses the workbox for PWA from registering a service worker to caching files.

At first, we need to make a build of CRA by running the command:

npm run build or yarn build

This will generate a build directory on the root of the project, now open ./build/service-worker.js file and add this snippet above workbox.core.clients();

workbox.routing.registerRoute(// Cache Image File/.*\.(?:png|jpg|jpeg|svg|gif)/,new workbox.strategies.StaleWhileRevalidate({cacheName: 'images',plugins: [new workbox.expiration.Plugin({maxEntries: 60,maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days}),],}));

Here are some assets you can download and edit by yourself: Click here

Now your CRA is successfully converted to PWA and supported in android/ios/windows phones.

Hope you like it. 😘

That’s All. ❤

--

--

Manal Liaquat
The Startup
Writer for

Javascript Geek: React.js, React-Native, PWA [iOS and Android] and UI/UX, developer and uses Firebase and Node.js for back-end work.