The purpose of this site is to build an active community for UIMinds, PHP, HTML, JavaScript, Jquery Developers and UI/UX Designers to Network, Exchange ideas and talk about Code, Architecture, Innovation, and open source in general. Share the Open Source, Examples, Inspirations and best practices.

Monday, November 27, 2017

Tutorial for Developing a Progressive Web App With ReactJS

In this tutorial, we'll learn how to create a simple React app, and use another tool to help us test it along the way. Let's get to it!

Progressive Web Apps (PWAs) have rapidly grown in popularity as essentially fast, performance-based web applications streamlined for delivering mobile app-like experiences. PWAs are built using HTML, CSS, and JavaScript to create a level of usability and performance that’s in parity to native mobile applications. They are responsive, consume lesser data and storage space, and supports push notifications and offline usage in the browser.

Building a progressive web app has now become a web development trend every enterprise wants to follow. Big players such as Twitter and Flipboard recently launched their progressive web apps to deliver mobile experiences to users, without requiring them to actually install the app. In this article, you will learn how to build a progressive web app using React. So, let’s get started.

Step 1 – Setting Up a React App

First, generate a React app with create-react-app. To do so, you need to run the following commands:

npm install -g create-react-app

create-react-app pwa-app

Now install React Router:

cd pwa-app

npm install --save react-router@3.0.5

You need to replace the “src/App.js” content using the below code to get a basic template with navigation.

importReact, { Component } from'react';

import { Router, browserHistory, Route, Link } from'react-router';

import'./App.css';

constNavBar= () => (

<divclassName="navbar">

<Linkto="/">Feed</Link>

<Linkto="/profile">Profile</Link>

</div>

);

constTemplate= ({ title }) => (

<div>

<NavBar/>

<pclassName="page-info">

Thisisthe {title} page.

</p>

</div>

);

constFeed= (props) => (

<Templatetitle="Feed"/>

);

constProfile= (props) => (

<Templatetitle="Profile"/>

);

classAppextendsComponent {

render() {

return (

<Routerhistory={browserHistory}>

<Routepath="/"component={Feed}/>

<Routepath="/profile"component={Profile}/>

</Router>

);

}

}

exportdefaultApp;

Now, you will have to update the default styles by replacing your “src/App.css” with the below styles to make you app look clean.

.navbar {

background-color: #01C8E5;

text-align: center;

}

.navbara {

display: inline-block;

padding: 10px;

color: #fff;

text-decoration: none;

}

.page-info {

text-align: center;

font-weight: bold;

}

Then run the “npm start” to test the app in the browser. This is a basic app with two routes. You will now convert it into a PWA.

Step 2 – Installing Lighthouse and Audit

Lighthouse is an automated, open source tool for testing applications against the PWA checklist. It facilitates audits for accessibility, performance, and more.

Test your app with Lighthouse. Click the Lighthouse icon from the top right corner in Chrome and then click on the ‘Generate Report’ button. The generated report will look like this:

You will have to fix all the failed audits.

Step 3 – Registering a Service Worker

Service workers are the proxy servers that connect the app and network. With Service Worker, you will have to intercept network requests and save cached files. This will enable your app to work even when the network is unavailable.

Create a blank worker.js file in your app’s public folder and add the following code to that file:

// Flag for enabling cache in production

vardoCache=false;

varCACHE_NAME='pwa-app-cache';

// Delete old caches

self.addEventListener('activate', event=> {

constcurrentCachelist= [CACHE_NAME];

event.waitUntil(

caches.keys()

.then(keyList=>

Promise.all(keyList.map(key=> {

if (!currentCachelist.includes(key)) {

returncaches.delete(key);

}

}))

)

);

});

// This triggers when user starts the app

self.addEventListener('install', function(event) {

if (doCache) {

event.waitUntil(

caches.open(CACHE_NAME)

.then(function(cache) {

fetch('asset-manifest.json')

.then(response=> {

response.json();

})

.then(assets=> {

// We will cache initial page and the main.js

// We could also cache assets like CSS and images

consturlsToCache= [

'/',

assets['main.js']

];

cache.addAll(urlsToCache);

})

})

);

}

});

// Here we intercept request and serve up the matching files

self.addEventListener('fetch', function(event) {

if (doCache) {

event.respondWith(

caches.match(event.request).then(function(response) {

returnresponse||fetch(event.request);

})

);

}

});

Now check if the browsers support the service workers and thereafter register worker.js. To do this, you need to add the following script to public/index.html (Note that “shrink-to-fit=no” from viewport meta tag has been removed).

You must restart your app and reload the browser after which you will notice the “Worker Registration Successful” message in the developer console. Now regenerate the Lighthouse report.

Step 4 – Improving Progressive Nature of the App

Your app will render an empty root div until the JavaScript loads and React hooks the initial route. You must ensure your app works without any JS loading and displays a bit of CSS and HTML before React comes into play. Your updated index.html will look like this:

Now use Lighthouse to re-audit your app and you will notice an improvement in the app's performance.

Step 5 – Adding Splash Icons

You’re required to add a 512x512 icon to show up on the splash screen. To do so, you will have to update the manifest.json and add the icon in the public folder.

{

"short_name": "React App",

"name": "Create React App Sample",

"icons": [

{

"src": "icon-192x192.png",

"sizes": "192x192",

"type": "image/png"

},

{

"src": "icon-512x512.png",

"sizes": "512x512",

"type": "image/png"

}

],

"start_url": "/",

"display": "standalone",

"theme_color": "#000000",

"background_color": "#ffffff"

}

Also, use the following meta tags to allow the browser to identify that your app is a PWA.

<!-- Tell the browser it's a PWA -->

<metaname="mobile-web-app-capable"content="yes">

<!-- Tell iOS it's a PWA -->

<metaname="apple-mobile-web-app-capable"content="yes">

Step 6 – Deploying the PWA

Now, just the HTTPS is missing and caching can be fixed after you deploy the app. Update the doCache flag with ‘true’ in the worker.js file. Create a new project in firebase-console and name it 'Pwa App.' Then run the following command in the project directory:

npm install -g firebase-tools

firebase login

firebase init

Your firebase.json should look like this:

{

"hosting": {

"public": "build",

"rewrites": [

{

"source": "**",

"destination": "/index.html"

}

]

}

}

After initialization, build and deploy your app.

npm run build

firebase deploy

You will see the following outcome after you audit the app using Lighthouse on the deployed URL.