Understanding Progressive Web Apps(PWA) with Angular: A Comprehensive Guide
Progressive Web Apps are web applications that work seamlessly and provide the same user experience independent of user device and network that leverage modern web capabilities to deliver an app-like experience to users. Key features of PWAs include:
- Reliability: PWAs load instantly and remain functional even in uncertain network conditions, thanks to service workers that cache essential resources.
- Speed: PWAs are designed to be fast and responsive, providing a smooth user experience, especially on mobile devices.
- Engagement: PWAs can be installed on users’ devices and offer features such as push notifications, making them highly engaging.
- Responsiveness: PWAs adapt seamlessly to various screen sizes and devices, ensuring a consistent experience across platforms
We would be leveraging Service Workers and convert our angular application into a Progressive Web App (PWA).
Table of Contents
· What are Service Workers?
· Getting Started with Progressive Web Apps
∘ Setting up your Angular Application
∘ Adding PWA Support :
∘ Building the App for Production
· Understanding Manifest & Customisation :
∘ Manifest File Properties
· Configuring Service Worker Behavior
∘ installMode
∘ updateMode
∘ resources
· Elevating Experience with Notification Badges
· Conclusion
What are Service Workers?
Service worker is a script that runs in the background of a web application, separate from the main browser thread. It acts as a programmable network proxy, intercepting and handling network requests made by the web application.
Some key functionalities of service workers are :
- Background Processing: Service workers run in the background, independent of the main browser thread. This allows them to perform tasks such as intercepting network requests, caching responses, and handling push notifications without affecting the user interface or responsiveness of the web application.
- Network Interception: Service workers can intercept and handle network requests made by the web application, enabling advanced caching strategies and offline capabilities. By intercepting requests, service workers can serve cached responses or dynamically generate responses based on custom logic.
- Caching: One of the primary uses of service workers is caching web resources such as HTML, CSS, JavaScript, images, and API responses. By caching resources locally, service workers enable PWAs to function offline or with limited network connectivity, providing users with a reliable experience regardless of their network status.
- Push Notifications: Service workers can receive push notifications from a server and display them to the user, even when the web application is not actively open in the browser. This allows PWAs to engage users with timely updates, notifications, and alerts, similar to native mobile applications.
- Background Sync: Service workers can perform background synchronization tasks, allowing the web application to sync data with a server even when the browser tab is closed or the device is offline. This enables features such as offline form submission, automatic data synchronization, and background updates.
- Security: Service workers run in a separate context from the web page, which provides enhanced security and mitigates the risk of malicious attacks. However, it’s essential to implement proper security measures to prevent unauthorized access and ensure the integrity of service worker scripts.
Getting Started with Progressive Web Apps
1. Setting up your Angular Application
First, create an angular application, you can do so using the following command.
ng new app_name
This creates and initializes a new angular application.
To demonstrate we have a Weather App which shows the current weather of the place you want.
Before we go ahead, if we head over to the network panel(Inspect Tools) and go offline.
Our page looks like this :
2. Adding PWA Support :
Run the following command in the terminal.
ng add @angular/pwa
This command will install the necessary dependencies and set up the project for Progressive Web App development.
In case you are adding it to your existing application and are facing dynamic import error update your cli version to latest minor version.
eg. Update you application to latest stable version of angular i.e 15.1.4 -> 15.2.11
You can use the use the following command for your caseng update @angular/cli@15 @angular/cli@15
Let’s take a look at all the changes made by the above command.
- It adds @angular/service-worker package in package.json.
- It creates an ngsw-config.json file at the root of the project and updates the build configuration in angular.json, which is a service worker configuration. This file defines the behavior of the Angular service worker, including caching strategies, asset groups, and routes to cache.
- Updates the angular.json with assets( manifest ) and ngswConfig path.
- It creates manifest.webmanifest in the src folder which contains all the information about the application to run natively.
- It adds service worker in the app.module.
- It also includes a Meta tag for theming and manifest file in the head element of index.html.
3. Building the App for Production
Build your app using the following command :
ng build
We will now run the application to check our newly added functionality, to do so we will be installing an external web server as angular-cli (ng-serve) does not work with service workers.
npm i -g -d http-server
This will add http-server as a development dependency & also install globally to use the command http-server. You can also use angular-http-server.
Next, run the following command :
http-server -p 8081 -c-1 dist/weather-app
here -p signifies the port and -c signifies the cache-time (in seconds) for cache-control max-age header, e.g. -c10
for 10 seconds. To disable caching, we are using -c-1
which indicates how long a resource can be served from the cache after it’s been downloaded.
Our app is now available at localhost:8081.
Now if you go offline using the network panel as before your app will be working as expected and you will not be working and you will not be getting the offline page as before. 🎉
Once you load you will be able to notice the following
You can click on install and our app will be available natively.
If you would notice our app is also available in the below URLs as well
However if you try those you will not be getting Install options, that is because PWA requires a secure connection and need can be served from localhost or HTTPS
If you head over to the application tab in your inspect tools you can see the registered service workers and cached data.
With this, we have successfully upgraded our app to a Progressive Web App 🚀and can be installed natively and also works offline🌐.
Now let’s delve deeper to understand the configuration and customize the app.
Understanding Manifest & Customisation :
A manifest file (manifest.webmanifest
) is a JSON file that provides metadata about a Progressive Web App (PWA) and enables installation capabilities on supported devices.
Manifest File Properties
The following properties are commonly found in a manifest file:
- name: The name of the application.
- short_name: A short name for the application (displayed on the home screen).
- start_url: The URL where the application should start when launched.
- display: Defines how the application should be displayed (e.g.,
standalone
,fullscreen
,minimal-ui
). - theme_color: The color of the application’s theme.
- background_color: The background color of the splash screen.
- icons: An array of icon objects representing different sizes of icons for the application.
In our case, we had the following configuration:
{
"name": "Weather",
"short_name": "Weather",
"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"
},
...
]
}
If we notice our app title bar after the installation was blue ie we had specified our theme_color as #1976d2.
To enable navigation buttons at the top we can update the display key to browser
or minimal-ui
Now if you re-build your app you can see the navigation button appear on the title bar.
You can review all these details in inspect tools of your application.
Configuring Service Worker Behavior
The ngsw-config.json
file is located in the root
directory of your Angular project. This file defines the behavior of the Angular service worker, including caching strategies, asset groups, and routes to cache.
{
"$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)"
]
}
}
]
}
Here each property signifies the following :
- The
index
property specifies the entry point of the application. - The
assetGroups
array defines groups of assets to be cached. In this case, there are two groups: "app" for application files (HTML, CSS, JS), and "assets" for static assets (images, fonts). - Each asset group has properties such as
installMode
,updateMode
, andresources
to configure caching behavior.
Asset groups are used to configure caching behavior in Angular service workers.
installMode
The installMode
property specifies how resources in an asset group should be installed or cached by the service worker. There are three possible values for installMode
:
- prefetch: Resources are fetched and cached in the background as soon as they are encountered by the service worker. This mode is suitable for resources that are likely to be used in the future but are not immediately required.
- lazy: Resources are only fetched and cached when they are requested by the application. This mode defers resource caching until they are needed, which can reduce the initial load time of the application.
- eager: Resources are fetched and cached immediately during the installation phase of the service worker. This mode ensures that essential resources are available offline as soon as the service worker is activated.
updateMode
The updateMode
property specifies how resources in an asset group should be updated or refreshed by the service worker. There are three possible values for updateMode
:
- prefetch: Resources are fetched and cached in the background, and updates are checked periodically. If updates are available, the new versions of resources are fetched and cached asynchronously.
- lazy: Resources are only updated when they are requested by the application. This mode defers update checks until resources are needed, which can reduce network usage and improve performance.
- eager: Resources are updated immediately during the installation phase of the service worker. This mode ensures that the latest versions of resources are available offline as soon as the service worker is activated.
resources
The resources
property specifies the resources that belong to an asset group and should be cached by the service worker. Resources can be defined using glob patterns or specific URLs.
Elevating Experience with Notification Badges
To add notification badges in Progressive Web Apps (PWAs) built with Angular, you can utilize the Badging API, which allows you to display badges on the app icon to inform users about new content or notifications waiting. Here’s how you can implement notification badges in Angular PWAs:
- Check Browser Support: Before using the Badging API, ensure that the browser engine your Angular PWA runs on supports the Badging API. You can check for support using JavaScript:
if (navigator.setAppBadge) {
// Badging API is supported
console.log("The Badging API is supported!");
}
- Displaying the Badge: To set a badge on the app icon, you can use the
navigator.setAppBadge()
method. You can display an empty badge or a badge with a number. Here's an example:
// Display an empty badge
navigator.setAppBadge();
// Display a number in the badge
navigator.setAppBadge(42);
- Handling Badge Updates: The
setAppBadge()
function returns a Promise, allowing you to manage when the badge is added and catch any potential errors. Here's an example:
navigator.setAppBadge(42).then(() => {
console.log("The badge was added");
}).catch(e => {
console.error("Error displaying the badge", e);
});
- Clearing the Badge: To remove the badge from the app icon, you can use the
navigator.clearAppBadge()
method. Here's how you can clear the badge:
navigator.clearAppBadge();
Conclusion
Diving into the realm of Progressive Web Apps (PWAs) with Angular offers a myriad of benefits, including enhanced reliability, speed, engagement, and responsiveness across various devices and network conditions. Leveraging the power of service workers, we’ve explored how they serve as programmable network proxies, enabling advanced caching strategies, offline capabilities, push notifications, background synchronization, and enhanced security.
Through a step-by-step guide, we’ve learned how to set up an Angular application, integrate PWA support, and configure service worker behavior to optimize caching and asset management. By understanding the significance of manifest files and customizations, we’ve enhanced the user experience and accessibility of our PWA.
As we’ve witnessed the seamless transition from a traditional web app to a PWA, we’ve embraced the future of web development, where applications can be installed natively, work offline, and deliver an immersive user experience akin to native mobile apps. Armed with these insights and practical knowledge, we’re equipped to embark on further exploration and customization, driving innovation and excellence in our Angular PWAs.
If you liked it so far, give it some claps 👏
Congratulations 🎉, You have won an exclusive preview of the above weather app here.