notepad/pwa.md

3.8 KiB

PWA (Progressive Web app)

The manifest file

{
	"name": "Full app name",
	"short_name": "app short name",
	"theme_color": "#",
	"background_color": "#",
	"description": "description about app",
	"dir": "ltr",
	"display": "standalone",
	"scope": "/",
	"start_url": "/",
	"icons": [
		{
			"src": "assets/icons/icon-72x72.png",
			"sizes": "72x72",
			"type": "image/png"
		},
		{
			"src": "assets/icons/icon-96x96.png",
			"sizes": "96x96",
			"type": "image/png"
		},
		{
			"src": "assets/icons/icon-128x128.png",
			"sizes": "128x128",
			"type": "image/png"
		},
		{
			"src": "assets/icons/icon-144x144.png",
			"sizes": "144x144",
			"type": "image/png"
		},
		{
			"src": "assets/icons/icon-152x152.png",
			"sizes": "152x152",
			"type": "image/png"
		},
		{
			"src": "assets/icons/icon-192x192.png",
			"sizes": "192x192",
			"type": "image/png"
		},
		{
			"src": "assets/icons/icon-384x384.png",
			"sizes": "384x384",
			"type": "image/png"
		},
		{
			"src": "assets/icons/icon-512x512.png",
			"sizes": "512x512",
			"type": "image/png"
		}
	]
}

For Apple devices

  <meta name="Title" content="Title of app" />
	<meta name="mobile-web-app-capable" content="yes" />
	<meta name="apple-mobile-web-app-capable" content="yes" />
	<meta name="application-name" content="name of application" />
	<meta name="apple-mobile-web-app-status-bar-style" content="#007db2" />
	<meta name="apple-mobile-web-app-title" content="title of app" />
	<meta name="msapplication-starturl" content="/" />
	<meta name="theme-color" content="#1976d2" />
	<meta
		name="Description"
		content="Description of the app"
	/>
	<link rel="icon" type="image/x-icon" href="favicon.ico" />
	<link
		rel="icon"
		sizes="96x96"
		href="assets/icons/icon-96x96.png"
		type="image/png"
	/>
	<link
		rel="apple-touch-icon"
		sizes="192x192"
		href="assets/icons/apple-touch-icon.png"
	/>		

Strategy

{
	"$schema": "path to schema.json",
	"index": "/index.html",
	"assetGroups": [
		{
			"name": "app",
			"installMode": "prefetch",
			"resources": {
				"files": [
					"/favicon.ico",
					"/index.html",
					"/manifest.json",
					"/*.css",
					"/*.js"
				],
				"urls": []
			}
		},
		{
			"name": "assets",
			"installMode": "lazy",
			"updateMode": "prefetch",
			"resources": {
				"files": [
					"/assets/**",
					"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
				]
			}
		}
	],
	"dataGroups": [
		{
			"name": "apis",
			"urls": [
				"urls to be stored to imporve performance of the app"
			],
			"cacheConfig": {
				"maxSize": 3,
				"maxAge": "1d",
				"timeout": "5s",
				"strategy": "performance"
			}
		},
		{
			"name": "quick-load",
			"urls": [
				"urls to be stored to get the latest value"
			],
			"cacheConfig": {
				"maxSize": 2,
				"maxAge": "5m",
				"timeout": "1m",
				"strategy": "performance"
			}
		}
	]
}

Service Worker Registration

	ServiceWorkerModule.register('path to service worker file', {
		enabled: <true/false/condition to return truthy>,
		registrationStrategy: 'registerImmediately',
	})

Show app version (for user and debug process)

import { version } from 'path to package.json';

Custom installation

Javascript

	let promptEvent;
	window.addEventListener('beforeinstallprompt', (event) => {
		this.promptEvent = event;
	});

	// On User Click to install
	this.promptEvent.prompt();
	this.promptEvent.userChoice.then((choiceResult) => {
		if (choiceResult.outcome === 'accepted') {
			this.promptEvent = null;
		}
	});

Force app update

	if ('serviceWorker' in navigator) {
		navigator.serviceWorker
			.getRegistrations()
			.then((registrations: ServiceWorkerRegistration[]) => {
				for (const registration of registrations) {
					registration.update();
				}
			});
	}

Show user if app is online

	navigator.onLine