Notes
- Service Worker
- Manifest File
- Push Notifications (Optional)
- Generate a Lighthouse Report
- CSV vs. Postgresql Flag
- Less CSS Preprocessor
- Local Deployment vs. GitHub Pages
- SPA, MPA, PWA Concepts
- Technologies Referenced
Background Story
I wanted to demonstrate how to build a PWA that uses a database to store user data locally and syncs with a remote database when online. I also wanted to demonstrate how to use a service worker to cache the app shell and data as well as a manifest file to allow the user to install the app on their device.
Definitions
To turn your website into a PWA, you'll need the following qualifications:
- HTTPS - Your site must be served over HTTPS . This is a requirement for service workers. If you don't have a certificate, you can use Let's Encrypt.
If you're deploying locally, you can still achieve a PWA by using localhost , but you won't be able to use a service worker or push notifications and it is strongly recommended that you use HTTPS for a production deployment.
- Service Worker - A Service Worker) is a script that runs in the background and allows you to control how your app handles network requests and cache data. It also allows you to send push notifications to the user (see instructions below for more details).
- Manifest File - A manifest file is a JSON file that contains metadata about your app. It allows you to specify the name of your app, the icons that will be used when the app is installed on a device, the background color of the splash screen, and more (see instructions below for more details).
- App Shell - The app shell is the minimal HTML , CSS , and JavaScript required to power the user interface of your app. It is the first thing that is cached by the service worker and is used to provide a fast, reliable, and engaging experience for the user.
- Offline Data Storage - A PWA must be able to store data locally on the user's device. This allows the user to continue using the app when they are offline. When the user is online, the data should be synced with a remote database.
- Responsive Design - A PWA must be responsive and work on all devices.
Built With
I used the following technologies to build this app:
- React (Frontend)
- TypeScript (JavaScript)
- Node.js (Backend/Server)
- Postgresql (Database)
- Scss/Sass/Less (CSS Preprocessors)
- Workbox Package (Service Worker)
- PWA Asset Generator Package (Manifest File)
- NPM (Package Manager)
- Webpack (Module Bundler)
By default, the application uses client/src/App.scss to style the application. The App.sass and App.css (compiled from Less) can be used as well, they're interchangable. Simply uncomment out the line for the CSS Preprocessor you want to use in the client/src/components/UserTable.tsx file.
Getting Started
- Install Postgresql and create a database named pwa_db_web_app .
- Use the database.sql file to create the tables and insert the data.
- Change your directory to the project directory and run the following commands:
- Install npm if you haven't already:
npm install
npm run build
- Start the client (frontend):
cd client npm start
- Start the server (if using a database):
cd server npm start
- Open your browser and navigate to http://localhost:3000/PWA-Demo-App to view the PWA application.
- Open Lighthouse in Chrome to generate your PWA report.
Notes
Service Worker
- I used Workbox to generate the service worker file. To do this, I installed Workbox in the client directory:
npm install workbox-cli --global
- Then generate the service worker file by running:
npx workbox generateSW workbox-config.js
Manifest File
- Use PWA Asset Generator to automatically generate JSON for your manisfest.json file as well as the icons for your logo to make it PWA complicit.
- To install PWA Asset Generator run:
npm install -g pwa-asset-generator
- Then create a logo.png file in the root directory of your project. The logo should be at least 512x512 pixels.
The logo should be square and have a transparent background.
- Then run (Assuming you are in the directory your logo file is in):
npx pwa-asset-generator logo.png icons
The images will be created in the icons directory.
Push Notifications (Optional)
- To send Push Notifications, you'll need to create a VAPID key pair. You can do this by running the following command:
npx web-push generate-vapid-keys
- Then copy the VAPID key pair and paste it into the server/src/routes/notifications.ts file.
- Then run the following command to start the server:
npm start
- Then open your browser and navigate to http://localhost:3000.
- Then open the Chrome Dev Tools and click on the Application tab.
- Then click on the Service Workers tab -> Push link -> Subscribe button -> Allow button.
- Then copy the Endpoint and paste it into the server/src/routes/notifications.ts file.
- Then run the following command to send a push notification:
curl -X POST -H "Content-Type: application/json" -d "\"title\": \"Hello World\", \"body\": \"This is a test notification\">" http://localhost:3001/notifications
- Then you should see a push notification in your browser.
Generate a Lighthouse Report
- Lighthouse is an open-source, automated tool for improving the quality of web pages. You can run it against any web page, public or requiring authentication. It has audits for performance, accessibility, progressive web apps, and more.
- To generate a Lighthouse report, open your browser and navigate to http://localhost:3000.
- Then open the Chrome Dev Tools and click on the Lighthouse tab.
- Click on the Generate Report button.
- I achieved the following perfect scores:
- Performance: 100
- Accessibility: 100
- Best Practices: 100
- SEO: 100
- Progressive Web App: 100
Remove the BMC Widget and FontAwesome CSS references in the index.html file for a perfect Lighthouse Score (see comments in the file on where to remove). I kept these in for production purposes, but loading third-party cookies and unused CSS libraries slows down the application and is generally not a good practice.
CSV vs. Postgresql Flag
- By default, I'm parsing the table from a Comma-separated values (CSV) file located in the client/src/data directory for hosting purposes. You can change this to use Postgresql by modifying the client/src/App.tsx file flag to false here:
const useCsv = true;
Less CSS Preprocessor
- To use Less, install the package via npm:
npm install -g less
- Then, change your directory to the src folder where the App.less file exists and run the following command to generate the .css file:
lessc App.less App.css
- Be sure to uncomment out the .css import in the client/src/components/UserTable.tsx file.
Local Deployment vs. GitHub Pages
- By default, I'm deploying the app to GitHub Pages. You can change this to deploy the app locally without using the repository name PWA-Demo-App or to your own GitHub Pages by modifying the following files:
"homepage": "http://localhost:3000",
GitHub Pages:
"homepage": "https://.github.io//",
navigator.serviceWorker.register('/service-worker.js').then(registration =>
GitHub Pages:
navigator.serviceWorker.register('//service-worker.js').then(registration =>
link rel pl-s">manifest" href pl-s">/manifest.json">
GitHub Pages:
link rel pl-s">manifest" href pl-s">//manifest.json">
"start_url": ".",
GitHub Pages:
"start_url": "//",
- Then cd client/public from the root directory and run the following command to deploy to GitHub Pages:
npm run deploy
Resources
SPA, MPA, PWA Concepts
- Progressive Web Apps
- Wikipedia - Progressive Web App
- Single-Page Applications vs Multi-Page Applications: The Battle of the Web Apps
- Single Page Application (SPA) vs Multi Page Application (MPA): Which Is The Best?
Technologies Referenced
Happy Coding!
License
This project is released under the terms of the MIT License, which permits use, modification, and distribution of the code, subject to the conditions outlined in the license.
- The MIT License provides certain freedoms while preserving rights of attribution to the original creators.
- For more details, see the LICENSE file in this repository. in this repository.
Credits
Author: Scott Grivner
Email: scott.grivner@gmail.com
Website: scottgrivner.dev
Reference: Main Branch
About
A Progressive Web App (PWA) demo that uses React, TypeScript, Node.js, Postgresql, and Scss/Sass/Less. Learn about PWAs and achieving a perfect Lighthouse score.