What is Angular PWA?
A progressive web application (PWA) is an application built using web technologies like HTML CSS JAVASCRIPT. PWA uses service worker browser API to provide access to some native features. Also, it gives you an app-like feel. Cache storage is a really great feature.
Advantages:
- Offline mode
PWAs can be cached by the web browser and used even when offline. That’s great news for businesses with product catalogs because it allows their customers to browse products even when not connected to the internet.
- No installation or manual updates required.
To use Twitter’s progressive web app, there’s no need to visit the Play Store or App Store to install it. Users can simply visit mobile.twitter.com and log in without any delays. When Twitter updates its PWA, users don’t have to install it manually – all new features and bug fixes are available without any manual action required.
- Improved performance
PWAs utilize the so-called service workers, which are JavaScript files that run separately from the main browser thread and proactively control the caching of assets, they can deliver much better performance than traditional web apps.
- Platform-specific features
PWAs can live on the user’s home screen and deliver web push notifications that appear just like regular push notifications.
- App store independent
PWAs are app store-independent, which is great news for smaller businesses and independent app developers that don’t want to pay an annual fee.
Follow the steps below to create a PWA in Angular.
- Create an Angular application
- Add @angular/pwa package
- Understand the files added/modified by @angular/pwa package
- Run the application locally
We’re going to follow each and every step in detail.
- Create an Angular application
we will be using the Angular CLI.
npm install -g @angular/cli
ng new angular-pwa-1
cd angular-pwa-1 && code .ng add @angular/material
- Add @angular/pwa package
Now we’re ready to add the @angular/pwa package.
ng add @angular/pwa
- Understand the files added/modified by @angular/pwa package
It adds different png files for different splash images for various resolutions. it adds ngsw-config.json and manifest.webmanifest for configuration purposes. Also, it modifies angular.json, package.json, index.html and app.module.ts.
ngsw-config.json
It’s a configuration file in JSON format. Mainly this file is responsible for the generation of ngsw-worker.js
{ "$schema": "./node_modules/@angular/service-worker/config/schema.json", "index": "/index.html", "assetGroups": [ { "name": "app", "installMode": "prefetch", "resources": { "files": [ "/favicon.ico", "/index.html", "/manifest.webmanifest", "/*.css", "/*.js" ] } }, { "name": "assets", "installMode": "lazy", "updateMode": "prefetch", "resources": { "files": [ "/assets/**", "/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)" ] } } ] }
manifest.webmanifest
It consists of how the PWA application will look when it opens up. Here you can set options like splash screen icon, background color, display, etc.
{ "name": "angular-pwa-1", "short_name": "angular-pwa-1", "theme_color": "#1976d2", "background_color": "#fafafa", "display": "standalone", "scope": "./", "start_url": "./", "icons": [ { "src": "assets/icons/icon-72x72.png", "sizes": "72x72", "type": "image/png", "purpose": "maskable any" }, { "src": "assets/icons/icon-96x96.png", "sizes": "96x96", "type": "image/png", "purpose": "maskable any" }, { "src": "assets/icons/icon-128x128.png", "sizes": "128x128", "type": "image/png", "purpose": "maskable any" }, { "src": "assets/icons/icon-144x144.png", "sizes": "144x144", "type": "image/png", "purpose": "maskable any" }, { "src": "assets/icons/icon-152x152.png", "sizes": "152x152", "type": "image/png", "purpose": "maskable any" }, { "src": "assets/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable any" }, { "src": "assets/icons/icon-384x384.png", "sizes": "384x384", "type": "image/png", "purpose": "maskable any" }, { "src": "assets/icons/icon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable any" } ] }
angular.json
Added src/manifest.webmanifest file under assets, so that it will be served with the site. That links ngswConfigPath and serviceWorker enabling the production configuration in build schematics.
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "angular-pwa-1": { "projectType": "application", "schematics": {}, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/angular-pwa-1", "index": "src/index.html", "main": "src/main.ts", "polyfills": [ "zone.js" ], "tsConfig": "tsconfig.app.json", "assets": [ "src/favicon.ico", "src/assets", "src/manifest.webmanifest" ], "styles": [ "src/styles.css" ], "scripts": [], "serviceWorker": true, "ngswConfigPath": "ngsw-config.json" }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kb", "maximumError": "1mb" }, { "type": "anyComponentStyle", "maximumWarning": "2kb", "maximumError": "4kb" } ], "outputHashing": "all" }, "development": { "buildOptimizer": false, "optimization": false, "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { "browserTarget": "angular-pwa-1:build:production" }, "development": { "browserTarget": "angular-pwa-1:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "angular-pwa-1:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "polyfills": [ "zone.js", "zone.js/testing" ], "tsConfig": "tsconfig.spec.json", "assets": [ "src/favicon.ico", "src/assets", "src/manifest.webmanifest" ], "styles": [ "src/styles.css" ], "scripts": [] } } } } } }
app.module.ts
“app.module.ts is used to import the ServiceWorkerModule for registering ngsw-config.js
import { NgModule, isDevMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { ServiceWorkerModule } from '@angular/service-worker'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, ServiceWorkerModule.register('ngsw-worker.js', { enabled: !isDevMode(), registrationStrategy: 'registerWhenStable:30000' }) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
- Run the application locally
- Run ng build –prod command. It will create files under dist/angular-pwa-1 folder.
- Navigate to that folder using cd dist/angular-pwa-1
- Run http-server command (npm i -g http-server)
- Open
http-server -p 8080 -c-1 dist/angular-pwa-1 -o