Skip to content

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.

License

Notifications You must be signed in to change notification settings

scottgriv/PWA-Demo-App

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


React Badge TypeScript Badge Postgresql Badge
Node.js Badge Less Badge Sass Badge
GitHub Badge Email Badge BuyMeACoffee Badge
GitHub Workflow Status (with event) Silver


🖥️ PWA Demo 💻

This Progressive Web App (PWA) demo showcases the cutting-edge capabilities of web technology by utilizing a robust stack including React, TypeScript, Node.js, PostgreSQL, and styling with Scss/Sass/Less. Designed as both an educational tool and a practical demonstration, it guides users through the intricacies of building a high-performance PWA capable of achieving a perfect Lighthouse score. The project not only highlights best practices for web development and performance optimization but also offers insights into creating seamless, app-like experiences on the web, making it an invaluable resource for developers looking to enhance their skills in crafting modern, efficient web applications.

  • View a demo of the project on GitHub Pages Here.

Application Preview

Table of Contents

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.

Note

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)

Note

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

  1. Install Postgresql and create a database named pwa_db_web_app.
  • Use the database.sql file to create the tables and insert the data.
  1. Change your directory to the project directory and run the following commands:
  • Install npm if you haven't already:
npm install
  • Build the application:
npm run build
  • Start the client (frontend):
cd client
npm start
  • Start the server (if using a database):
cd server
npm start
  1. Open your browser and navigate to http://localhost:3000/PWA-Demo-App to view the PWA application.
  2. 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.

Tip

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
  • References to the Lighthouse Report files are located in the docs directory.

Important

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:
  1. /client/package.json

    Local:

    "homepage": "http://localhost:3000",

    GitHub Pages:

    "homepage": "https://{your_github_username}.github.io/{your_repository_name}/",
  2. /client/src/index.tsx

    Local:

    navigator.serviceWorker.register('/service-worker.js').then(registration => {

    GitHub Pages:

    navigator.serviceWorker.register('/{your_repository_name}/service-worker.js').then(registration => {
  3. /client/public/index.html

    Local:

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

    GitHub Pages:

    <link rel="manifest" href="/{your_repository_name}/manifest.json">
  4. /client/public/manifest.json

    Local:

    "start_url": ".",

    GitHub Pages:

    "start_url": "/{your_repository_name}/",
  • Then cd client/public from the root directory and run the following command to deploy to GitHub Pages:

    npm run deploy
  • If you're unfamiliar with deploying a static site to GitHub Pages, you can read more about it here: GitHub Pages.

Resources

SPA, MPA, PWA Concepts

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.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published