Step-by-Step: Build a Progressive Web App with Angular 18 and Workbox 7.0
Progressive Web Apps (PWAs) combine the reach of web apps with the functionality of native apps, including offline access, push notifications, and installability. Angular 18 streamlines PWA development, and pairing it with Workbox 7.0 gives you granular control over service worker caching and behavior. This guide walks you through building a production-ready PWA from scratch.
Prerequisites
- Node.js 18.19+ installed (required for Angular 18)
- Angular CLI 18+ installed globally:
npm install -g @angular/cli@18 - Basic familiarity with Angular components, services, and CLI commands
- Workbox CLI 7.0 (we'll install this later)
Step 1: Create a New Angular 18 Project
Open your terminal and run the following command to scaffold a new Angular project:
ng new angular-pwa-demo --routing --style=css
cd angular-pwa-demo
This creates a project with routing enabled and CSS for styling. You can adjust the style flag to use SCSS or another preprocessor if preferred.
Step 2: Install PWA and Workbox 7.0 Dependencies
First, add the official Angular PWA package, which integrates Workbox with Angular's build pipeline:
ng add @angular/pwa@18
This command automatically configures your project to use service workers, adds a default ngsw-config.json (Workbox configuration file), and updates your angular.json to generate service worker assets during build.
Next, install Workbox 7.0 and the Workbox CLI as dev dependencies to customize your service worker:
npm install workbox@7.0 workbox-cli@7.0 --save-dev
Verify the installed Workbox version by checking your package.json to ensure it's 7.0.x.
Step 3: Configure Workbox 7.0 for Your PWA
Open the ngsw-config.json file in your project root. This is the Workbox configuration file that Angular's service worker uses. Update it to use Workbox 7.0 features and define your caching strategies:
{
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(eot|svg|cur|jpg|jpeg|png|gif|webp|typescript|ttf|woff|woff2|ani)"
]
}
}
],
"dataGroups": [
{
"name": "api-freshness",
"urls": ["/api/**"],
"cacheConfig": {
"strategy": "freshness",
"maxSize": 100,
"maxAge": "1h",
"timeout": "5s"
}
}
]
}
This configuration prefetches core app assets, lazily loads and caches static assets, and uses a freshness strategy for API calls (serves cached data if the network times out after 5 seconds).
Step 4: Create a Custom Service Worker (Optional)
If you need advanced Workbox 7.0 features not covered by ngsw-config.json, create a custom service worker file. First, create a src/custom-sw.js file:
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';
// Precache assets injected by Angular's build process
precacheAndRoute(self.__WB_MANIFEST);
// Cache images with stale-while-revalidate strategy
registerRoute(
({ request }) => request.destination === 'image',
new StaleWhileRevalidate({
cacheName: 'image-cache',
})
);
Then update your angular.json to include this custom service worker in the build output. Add the following to the architect.build.options section:
"serviceWorker": true,
"ngswConfigPath": "ngsw-config.json",
"customServiceWorker": "src/custom-sw.js"
Note: Angular 18's PWA support may require additional configuration for custom service workers; refer to the official Angular PWA documentation for compatibility details.
Step 5: Enable Offline Support
To test offline support, add a simple component that fetches data from an API. Generate a new component:
ng generate component offline-demo
Update the component's TypeScript file to fetch data from a public API (e.g., JSONPlaceholder):
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Component({
selector: 'app-offline-demo',
template: `
Post Title: {{ data.title }}
{{ data.body }}
Loading...
`
})
export class OfflineDemoComponent implements OnInit {
data$!: Observable;
constructor(private http: HttpClient) {}
ngOnInit() {
this.data$ = this.http.get('https://jsonplaceholder.typicode.com/posts/1');
}
}
Add this component to your app's routing module to access it via a URL.
Step 6: Build and Test Your PWA
First, build your Angular project for production:
ng build
This generates a dist/angular-pwa-demo folder with your production-ready app and service worker files. To test the PWA, serve the build output using a local HTTP server (required for service workers to work, as they don't run on file:// protocol):
npx http-server dist/angular-pwa-demo -p 8080
Open Chrome and navigate to http://localhost:8080. Open Chrome DevTools, go to the Application tab, then Service Workers. You should see your service worker registered and activated.
Test offline support: Go to the Network tab, check "Offline", then refresh the page. Your app should still load, and the offline-demo component should display cached API data (if you visited the route while online first).
Run a Lighthouse audit (Lighthouse tab in DevTools) to verify PWA compliance: you should see checks for service worker registration, offline support, and installability pass.
Step 7: Deploy Your PWA
PWAs require HTTPS to work in production (except localhost). Deploy your dist/angular-pwa-demo folder to a static hosting provider that supports HTTPS, such as Firebase Hosting, Netlify, or Vercel. Most providers automatically handle service worker headers, but verify that ngsw.json and worker-basic.min.js (or your custom service worker) are served correctly.
Conclusion
You've now built a fully functional PWA with Angular 18 and Workbox 7.0, with offline support, caching strategies, and PWA compliance. You can extend this further by adding push notifications, background sync, or custom install prompts. Workbox 7.0's extensive plugin ecosystem and Angular's built-in PWA tooling make it easy to scale your PWA as your app grows.
Top comments (0)