Angular PWA Introduction
What is a Progressive Web Application (PWA)?
Progressive Web Applications (PWAs) represent a modern approach to web development that combines the best of web and mobile applications. PWAs are web applications that use modern web capabilities to provide users with an experience similar to native applications.
At their core, PWAs are:
- Reliable: They load instantly and never show the "downasaur" (offline dinosaur) when there's no network connection
- Fast: They respond quickly to user interactions with smooth animations and jank-free scrolling
- Engaging: They feel like a natural app on the device, with an immersive user experience
Why Build PWAs with Angular?
Angular provides excellent support for developing PWAs through the @angular/pwa
package. Here are some benefits of building PWAs with Angular:
- Built-in PWA Support: Angular CLI makes adding PWA features straightforward with a simple command
- Service Worker Integration: Simplified management of service workers for offline capabilities
- App Shell Architecture: Angular facilitates implementing the app shell pattern for instant loading
- Tooling: Comprehensive tools for building, testing, and deploying PWAs
Key PWA Features in Angular
Service Workers
Service workers act as proxy servers that sit between web applications, the browser, and the network. They enable:
- Offline capabilities
- Background sync
- Push notifications
- Content caching
Web App Manifest
A JSON file that provides information about a web application, including:
- App name and description
- Icons for different screen sizes
- Theme colors
- Display mode (standalone, fullscreen, etc.)
App Shell Architecture
An application shell is the minimal HTML, CSS, and JavaScript required to power the user interface. It:
- Loads quickly on repeat visits
- Provides instant, reliable performance
- Displays content while awaiting data
Setting Up Your First Angular PWA
Let's walk through creating a basic Angular PWA:
Step 1: Create a new Angular project
ng new my-pwa-app
cd my-pwa-app
Step 2: Add PWA capabilities using Angular CLI
ng add @angular/pwa
This command performs several important changes to your application:
- Adds the
@angular/service-worker
package - Enables service worker support in the Angular CLI
- Imports and registers the service worker in the app module
- Updates the
index.html
file with a link to the manifest file and theme color - Creates icons for the PWA
- Creates the configuration file for the service worker (
ngsw-config.json
)
Let's examine what the updated app.module.ts
looks like:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ServiceWorkerModule } from '@angular/service-worker';
import { AppComponent } from './app.component';
import { environment } from '../environments/environment';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production,
// Register the ServiceWorker as soon as the application is stable
// or after 30 seconds (whichever comes first)
registrationStrategy: 'registerWhenStable:30000'
})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 3: Inspect the ngsw-config.json file
This file configures the service worker and controls how it caches resources:
{
"$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)"
]
}
}
]
}
Step 4: Inspect the web manifest file
The manifest.webmanifest
file contains metadata about your application:
{
"name": "my-pwa-app",
"short_name": "my-pwa-app",
"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"
},
// More icon definitions...
{
"src": "assets/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable any"
}
]
}
Step 5: Build and test your PWA
To test your PWA, you need to build it in production mode and serve it:
ng build --configuration production
After building, you can use a simple HTTP server to serve your PWA:
npx http-server -p 8080 -c-1 dist/my-pwa-app
Open your browser and navigate to http://localhost:8080
. You can inspect the service worker in the browser's developer tools under the "Application" tab.
Real-World Example: Creating an Offline-Capable News App
Let's consider a practical example of how PWAs can improve user experience.
Scenario: News Application
Imagine we're building a news application where users should be able to:
- Read news articles even when offline
- Receive push notifications for breaking news
- Install the app on their home screen
Implementing Offline News Reading
First, we'll configure our service worker to cache news articles:
// In ngsw-config.json, add a dataGroups section:
{
// ... existing configuration
"dataGroups": [
{
"name": "news-api",
"urls": [
"https://api.example.com/news"
],
"cacheConfig": {
"strategy": "freshness",
"maxSize": 100,
"maxAge": "1h",
"timeout": "10s"
}
}
]
}
Then, in our news service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class NewsService {
private readonly NEWS_API_URL = 'https://api.example.com/news';
private cachedNews: any[] = [];
constructor(private http: HttpClient) {}
getNews(): Observable<any[]> {
return this.http.get<any[]>(this.NEWS_API_URL).pipe(
tap(news => this.cachedNews = news),
catchError(() => {
console.log('Returning cached news due to network error');
return of(this.cachedNews);
})
);
}
}
Adding Push Notifications
To enable push notifications in our Angular application:
// In app.component.ts
import { SwPush } from '@angular/service-worker';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
readonly VAPID_PUBLIC_KEY = 'your-public-key-here';
constructor(private swPush: SwPush) {}
subscribeToNotifications() {
this.swPush.requestSubscription({
serverPublicKey: this.VAPID_PUBLIC_KEY
})
.then(sub => {
// Send subscription to server
console.log('Successfully subscribed to notifications', sub);
})
.catch(err => console.error('Could not subscribe to notifications', err));
}
}
<!-- In app.component.html -->
<button (click)="subscribeToNotifications()">
Subscribe to Breaking News Alerts
</button>
Testing PWA Features
To thoroughly test your Angular PWA:
-
Offline Testing: Enable "Offline" mode in Chrome DevTools' Network tab to verify your app works without a connection
-
Lighthouse Audit: Run a Lighthouse audit in Chrome DevTools to get a PWA score and recommendations for improvement
-
Installation Testing: Confirm your app shows the "Add to Home Screen" prompt and installs correctly
-
Push Notifications: Test if notifications appear correctly when triggered
Summary
In this introduction to Angular PWAs, we've learned:
- What Progressive Web Applications are and their core features
- How Angular supports PWA development through built-in tools
- The key components of a PWA: service workers, web app manifest, and app shell
- How to set up a basic Angular PWA project
- A real-world example of implementing offline capabilities and push notifications
PWAs represent the future of web development, combining the reach of web applications with the capabilities of native apps. With Angular's robust tooling and your new understanding of PWA concepts, you're well-positioned to build modern, responsive applications that work seamlessly across devices and network conditions.
Additional Resources
- Angular Service Worker Introduction
- MDN Web Docs: Progressive Web Apps
- Google's PWA Checklist
- Workbox - Tools for PWA
Exercises
- Create a simple Angular PWA that displays a list of items and allows users to view them offline.
- Modify the
ngsw-config.json
file to cache API responses from an external service. - Implement a "new content available" notification when your PWA has an update.
- Add custom install prompts to improve the user experience when adding your PWA to the home screen.
- Build a PWA that syncs user data when coming back online after being offline.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)