How to create Progressive Web Apps (PWA) with React Native
Mobile Applications

How to create Progressive Web Apps
(PWA) with React Native

By Vishal Sahu

How to create Progressive Web Apps (PWA) with React Native

Progressive Web Applications (PWAs) in recent years have grown to be one of the most widely used development methodology for mobile application development. Besides being widely used, PWAs have a great number of traditional as well as other benefits as follows:

  • Progressive enhancement
  • Native-like experience
  • Responsiveness
  • Offline Storage

Progressive Web App (PWA) in itself is a completely fresh and new web app development methodology. Unlike native mobile applications, PWAs are a hybrid of regular web pages or websites which open in mobile as a native app. This new development model aims to combine the modern-day website experience with the convenient benefits of mobile applications. They use HTTPS, a manifest file, service workers and an app shell architecture in harmony to deliver native app experiences to web applications.

One of the most well-known examples of a PWA, Twitter Lite saw an increase of up to 65% in 75% in Tweets and a 20% decrease in bounce rate. Twitter Lite is observed to load in under 3 seconds for repeat visits even on slow mobile networks. Forbes’ progressive web app test saw about 2× increase in the session length of the average user, 6× completion rate, and 20% more impressions. for PWAs convert five to six times more often compared to native ad banners. 

Let’s make a real-time progressive web application named PusherCoins to look at past current cryptocurrency prices in React Native.

Build PWA With React Native

We are going to use the create-react-app package that includes the global command for Create React App to help us build a real time PWA. create-react-app eliminates the hassle of setting up and configuring the applications and helps us build out applications with little to no configuration required. Also, credit to the sw-precache-webpack-plugin, which comes integrated into the production configuration, the production build of create-react-app is a fully functional PWA.

Install the create-react-app tool using the following command.

npm install -g create-react-app

Once the installation is done, we can create a new app using the following command

create-react-app pushercoins

This command will create an application and generate a new folder with all the files required to run the React Native app and a service worker file. A manifest file is also simultaneously created inside the public folder.

Progressive Web Apps (PWA) with React Native - 1

The manifest.json file that can be found in the public folder of the app is a simple JSON file that gives us the ability to control the appearance of the app and define its look and feel at launch.

{
"short_name": "PusherCoins",
"name": "PusherCoins",
"icons": [
{
"src": "favicon.ico",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

We notify the mobile app of the manifest.json file by linking to it in line 12 of the index.html file.

<link rel="manifest" href="%PUBLIC_URL%/manifest.json">

The service worker code registers a service worker for the React app. To find out if the service worker code really works we need to prepare the react app for production. The npm run build builds the application to the build folder and correctly bundles React in production mode. The output to the terminal looks like this.

Code

We get to see the various file sizes in our mobile app and the steps to run the application with the aid of a static server. We will be using the serve package for this. The commands can be used to set up a static server is as follow:

npm i serve –g

serve -s build

The application should be now up and running at http://localhost:5000. Using the ‘Application’ tab in the Developer Tools of the browser we can check is our site is a PWA. This check can also be performed using the Lighthouse tool.

As we are building a PWA with react, it is very important to think in terms of React components. Therefore, the react app can be majorly divided into three parts.

  1. js: All the code needed to show the previous prices of BTC, ETH, and LTC.
  2. js: All the code needed to show the recent price of BTC, ETH, and LTC.
  3. js: Both History.js and Today.js

To continue building the app we will need to create two new folders inside the src named Today and History. In the newly created directories, create the files Today.js, Today.css and History.js, History.css respectively. The directory should look like the one below.

Progressive Web Apps (PWA) with React Native - 2

Before getting started on the Today and History components, we need to build the app shell. An app shell is the minimal JavaScript HTML and CSS and that is required to drive the user interface (UI) and when cached offline can ensure instant, reliably good performance to users on repeat visits.

Open up the App.js file and alter with:

// Import React and Component
import React, { Component } from 'react';
// Import CSS from App.css
import './App.css';
// Import the Today component to be used below
import Today from './Today/Today'
// Import the History component to be used below
import History from './History/History'

class App extends Component {
render() {
return (
<div className="">
<div className="topheader">
<header className="container">
<nav className="navbar">
<div className="navbar-brand">
<span className="navbar-item">PusherCoins</span>
</div>
<div className="navbar-end">
<a className="navbar-item" href="https://pusher.com" target="_blank" rel="noopener noreferrer">Pusher.com</a>
</div>
</nav>
</header>
</div>
<section className="results--section">
<div className="container">
<h1>PusherCoins is a realtime price information about<br></br> BTC, ETH and LTC.</h1>
</div>
<div className="results--section__inner">
<Today />
<History />
</div>
</section>
</div>
);
}
}

export default App

Next, also replace the contents of App.css with the following.

.topheader {
background-color: #174c80;
}
.navbar {
background-color: #174c80;
}
.navbar-item {
color: #fff;
}
.results--section {
padding: 20px 0px;
margin-top: 40px;
}
h1 {
text-align: center;
font-size: 30px;
}

We will also be using the Bulma CSS framework. Add below line of code to your index.html in public folder:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.3/css/bulma.min.css">

Create the React Components

We first need to import React and its Component module using ES6 import. We also need to import axios.

import React, { Component } from 'react';
import './Today.css'
import axios from 'axios'

The code for Today and History can be found in the following GitHub project.

After the code for Today and History is complete we can run the npm start command to see the application at http://localhost:3000. We can also check how the app is currently faring as a PWA. We need to run the application in production mode using npm run build and then check the PWA status using Lighthouse.

Furthermore, we can add real-time functionalities using Pusher.

Make It Real-Time Using Pusher

Making use of Pusher, we can add real-time functionalities in the application. Pusher makes it super simple and convenient to bind UI interactions to events that are triggered by the client or server.

To set up pusher, we need to log into the dashboard and create a new app. We then need to copy the app _id, key, secret, and cluster and store them somewhere for future use.

Following this, we will need to set up a server that will help trigger events with Pusher. This server will be created in node.js. We will need to create a file named server.js in the root directory of the project and type in the following code.

// server.js
const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const app = express()
const Pusher = require('pusher')

//initialize Pusher with your appId, key, secret and cluster
const pusher = new Pusher({
appId: 'APP_ID',
key: 'APP_KEY',
secret: 'APP_SECRET',
cluster: 'YOUR_CLUSTER',
encrypted: true
})

// Body parser middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))

// CORS middleware
app.use((req, res, next) => {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*')
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE')
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type')
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true)
// Pass to next layer of middleware
next()
})

// Set port to be used by Node.js
app.set('port', (5000))

app.get('/', (req, res) => {
res.send('Welcome')
})

// API route in which the price information will be sent to from the clientside
app.post('/prices/new', (req, res) => {
// Trigger the 'prices' event to the 'coin-prices' channel
pusher.trigger( 'coin-prices', 'prices', {
prices: req.body.prices
});
res.sendStatus(200);
})

app.listen(app.get('port'), () => {
console.log('Node app is running on port', app.get('port'))
})

The subsequent tweaking and setting up can be found in this article by Pusher.

Offline Strategies

If right now were offline, the application won’t be able to make any API calls to get various prices. One way to overcome this issue would be to use client-side storage. We can use localStorage to cache data.

Note that there are various types of client-side storage such as Session Storage, Cookies, IndexedDB, and WebSQL. For our demo purposes, localStorage is sufficient, however, for production builds, a solution like IndexedDB is advisable as it offers a better structure, multiple tables and databases, and more storage. 

Deploy the App To Production

To prepare the app for production the following command can be used.

npm run build

Further, we need to add a home route to index.html in our server.js file. Next, run the command npm init  to create a JSON file. And lastly, install the packages using

npm install express body-parser pusher

The application can now be seen using the server file in the build folder. The app should now be live at http://localhost:5000/ . The now deploy command deploys the app to Now and a live URL is automatically generated.

The app should now be deployed and the PWA status of the app can be checked using Lighthouse.

Install the App

One of the major features of A Progressive We Apps (PWAs) is the web app install banner. A Progressive Web Apps (PWAs) will install a web app install banner if the following conditions are met:

  • The PWA has a web app manifest file with:
  • A short_name for home screen
  • A 144 X 144 PNG image
  • A start_url that loads successfully
  • A service worker registered on the site
  • The PWA is served over HTTPS
  • The app is visited at least twice, with five-minute intervals between the visits

Conclusion

In an aforementioned way, we have seen how a PWA is build using React Native, Pusher, and service workers and how to use browser devtools to our advantage.

Progressive apps are highly economical and cost nearly half as compared to native mobile apps. The only catch with PWA is that PWAs don’t have support on all browsers and software yet. However, it is safe to assume that soon enough, PWAs will break this barrier and may become the future of app development.

Vishal Sahu : Vishal is an experienced, hands-on software architect involved in the architecture, design, and implementation of service-oriented architectures, mobile apps, and web-based systems. He has significant experience and expertise in application, integration, and architecture.

Get in Touch

Whether you’re just getting started with your app idea or you’re a multinational
trying to evolve your brand for the future, we’re ready

GET STARTED