Configuration types and utilities for service worker behavior, caching strategies, and manifest generation for Angular PWA applications.
Top-level configuration interface for defining service worker behavior and caching strategies.
/**
* Top-level Angular Service Worker configuration object
* Defines caching strategies, navigation behavior, and resource handling
*/
interface Config {
/**
* Custom application data included in service worker manifest
* Available in version events as appData property
*/
appData?: {};
/**
* Path to the application's index.html file
* Used as fallback for navigation requests
*/
index: string;
/**
* Array of asset groups defining static resource caching strategies
* Each group can have different install/update modes
*/
assetGroups?: AssetGroup[];
/**
* Array of data groups defining dynamic URL caching strategies
* Used for API endpoints and external resources
*/
dataGroups?: DataGroup[];
/**
* Array of URL patterns that should be treated as navigation requests
* Patterns use glob syntax (* wildcards supported)
*/
navigationUrls?: string[];
/**
* Strategy for handling navigation requests
* - 'freshness': Network-first approach
* - 'performance': Cache-first approach (default)
*/
navigationRequestStrategy?: 'freshness' | 'performance';
/**
* Maximum age for cached application shell resources
* Uses duration string format (e.g., '1d', '12h', '30m')
*/
applicationMaxAge?: Duration;
}Usage Examples:
// Basic configuration
const config: Config = {
index: '/index.html',
assetGroups: [
{
name: 'app',
installMode: 'prefetch',
resources: {
files: ['/favicon.ico', '/index.html', '/*.css', '/*.js']
}
}
]
};
// Advanced configuration
const config: Config = {
index: '/index.html',
appData: {
version: '1.2.3',
buildTime: '2024-01-15T10:30:00Z'
},
navigationRequestStrategy: 'performance',
applicationMaxAge: '1d',
assetGroups: [
{
name: 'app-shell',
installMode: 'prefetch',
updateMode: 'prefetch',
resources: {
files: ['/index.html', '/favicon.ico', '/manifest.json'],
urls: ['https://fonts.googleapis.com/**']
}
}
],
dataGroups: [
{
name: 'api-cache',
urls: ['/api/**'],
cacheConfig: {
strategy: 'freshness',
maxSize: 100,
maxAge: '1h',
timeout: '10s'
}
}
],
navigationUrls: [
'/**', // All routes
'!/**/*.*', // Except files with extensions
'!/**/__*', // Except Angular dev server files
'!/**/__*/**' // Except Angular dev server directories
]
};Configuration for static resource caching including app shell files, images, and external resources.
/**
* Configuration for a group of static assets
* Defines caching behavior for related files and URLs
*/
interface AssetGroup {
/**
* Unique name for this asset group
* Used in service worker logs and debugging
*/
name: string;
/**
* How assets are cached during initial service worker installation
* - 'prefetch': Download all assets immediately (default)
* - 'lazy': Download assets only when first requested
*/
installMode?: 'prefetch' | 'lazy';
/**
* How assets are updated when new service worker version detected
* - 'prefetch': Download all assets before activating (default)
* - 'lazy': Update assets when next requested
*/
updateMode?: 'prefetch' | 'lazy';
/**
* Resources included in this asset group
*/
resources: {
/**
* Local file patterns using glob syntax
* Relative to application root
*/
files?: Glob[];
/**
* External URL patterns using glob syntax
* Can include cross-origin resources
*/
urls?: Glob[];
};
/**
* Cache query options for this asset group
* Controls how URL parameters affect cache matching
*/
cacheQueryOptions?: Pick<CacheQueryOptions, 'ignoreSearch'>;
}Usage Examples:
// App shell assets (critical resources)
const appShell: AssetGroup = {
name: 'app-shell',
installMode: 'prefetch', // Download immediately
updateMode: 'prefetch', // Update before activation
resources: {
files: [
'/index.html',
'/favicon.ico',
'/manifest.json',
'/*.css',
'/*.js'
]
}
};
// Lazy-loaded assets (images, fonts)
const staticAssets: AssetGroup = {
name: 'static-assets',
installMode: 'lazy', // Download on demand
updateMode: 'lazy', // Update on demand
resources: {
files: [
'/assets/**', // All assets directory files
'/**/*.png', // All PNG images
'/**/*.jpg', // All JPEG images
'/**/*.woff2' // Font files
]
},
cacheQueryOptions: {
ignoreSearch: true // Ignore URL query parameters
}
};
// External resources
const externalAssets: AssetGroup = {
name: 'external',
installMode: 'lazy',
resources: {
urls: [
'https://fonts.googleapis.com/**',
'https://fonts.gstatic.com/**',
'https://cdn.example.com/assets/**'
]
}
};Configuration for dynamic URL caching including API endpoints and external data sources.
/**
* Configuration for a group of dynamic URLs
* Defines caching strategies for API calls and external data
*/
interface DataGroup {
/**
* Unique name for this data group
* Used in service worker logs and debugging
*/
name: string;
/**
* URL patterns using glob syntax
* Defines which URLs this group handles
*/
urls: Glob[];
/**
* Version number for this data group configuration
* Increment to invalidate existing cache entries
*/
version?: number;
/**
* Caching configuration for this data group
*/
cacheConfig: {
/**
* Maximum number of entries to cache for this group
* Oldest entries removed when limit exceeded
*/
maxSize: number;
/**
* Maximum age of cached entries
* Uses duration string format (e.g., '1d', '12h', '30m')
*/
maxAge: Duration;
/**
* Network timeout for requests
* Falls back to cache if network takes longer
*/
timeout?: Duration;
/**
* Time before cached entry considered stale
* Triggers background refresh while serving stale content
*/
refreshAhead?: Duration;
/**
* Caching strategy for this data group
* - 'freshness': Network-first with cache fallback
* - 'performance': Cache-first with network update (default)
*/
strategy?: 'freshness' | 'performance';
/**
* Whether to cache opaque responses (CORS-blocked responses)
* Useful for third-party APIs that don't allow CORS
*/
cacheOpaqueResponses?: boolean;
};
/**
* Cache query options for this data group
* Controls how URL parameters affect cache matching
*/
cacheQueryOptions?: Pick<CacheQueryOptions, 'ignoreSearch'>;
}Usage Examples:
// API endpoints with freshness strategy
const apiData: DataGroup = {
name: 'api-data',
urls: [
'/api/users/**',
'/api/posts/**',
'/api/comments/**'
],
version: 1,
cacheConfig: {
strategy: 'freshness', // Network first
maxSize: 100, // Cache up to 100 responses
maxAge: '1h', // Cache for 1 hour
timeout: '5s', // 5 second network timeout
refreshAhead: '10m' // Refresh 10 minutes before expiry
}
};
// Static data with performance strategy
const staticData: DataGroup = {
name: 'static-data',
urls: ['/api/config', '/api/settings'],
cacheConfig: {
strategy: 'performance', // Cache first
maxSize: 10,
maxAge: '1d', // Cache for 1 day
timeout: '3s'
},
cacheQueryOptions: {
ignoreSearch: true // Ignore query parameters
}
};
// Third-party API with opaque responses
const externalData: DataGroup = {
name: 'external-api',
urls: ['https://api.external.com/**'],
cacheConfig: {
strategy: 'performance',
maxSize: 50,
maxAge: '30m',
cacheOpaqueResponses: true // Allow CORS-blocked responses
}
};Classes and utilities for generating service worker manifests from configuration.
/**
* Service worker manifest generator
* Converts configuration to runtime manifest format
*/
class Generator {
/**
* Create generator instance with filesystem interface
* @param fs - Filesystem implementation for reading files (readonly)
* @param baseHref - Base URL for resolving relative paths (private)
*/
constructor(readonly fs: Filesystem, private baseHref: string);
/**
* Process configuration and generate service worker manifest
* @param config - Service worker configuration
* @returns Promise resolving to generated manifest object
*/
process(config: Config): Promise<Object>;
}
/**
* Filesystem interface for manifest generation
* Implement for different environments (Node.js, browser, etc.)
*/
interface Filesystem {
/**
* List files in directory
* @param dir - Directory to list
* @returns Promise resolving to array of file paths
*/
list(dir: string): Promise<string[]>;
/**
* Read file contents as string
* @param file - File path to read
* @returns Promise resolving to file contents
*/
read(file: string): Promise<string>;
/**
* Get file hash for cache busting
* @param file - File path to hash
* @returns Promise resolving to file hash
*/
hash(file: string): Promise<string>;
/**
* Write file contents
* @param file - File path to write
* @param contents - File contents to write
* @returns Promise resolving when write completes
*/
write(file: string, contents: string): Promise<void>;
}/**
* Glob pattern string for matching files and URLs
* Supports * (any characters) and ** (any path) wildcards
*/
type Glob = string;
/**
* Duration string in human-readable format
* Examples: '1d' (1 day), '12h' (12 hours), '30m' (30 minutes), '45s' (45 seconds)
*/
type Duration = string;{
"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|png|webp|gif|otf|ttf|woff|woff2|ani)"
]
}
}
]
}{
"index": "/index.html",
"applicationMaxAge": "1d",
"navigationRequestStrategy": "performance",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": ["/index.html", "/*.css", "/*.js"]
}
}
],
"dataGroups": [
{
"name": "api-cache",
"urls": ["/api/**"],
"cacheConfig": {
"strategy": "freshness",
"maxSize": 100,
"maxAge": "1h",
"timeout": "5s"
}
}
],
"navigationUrls": [
"/**",
"!/**/*.*",
"!/**/__*"
]
}The Angular CLI provides commands for generating and validating service worker configurations:
# Generate ngsw.json manifest from ngsw-config.json
ngsw-config dist/my-app ngsw-config.json
# Using the Node.js CLI directly
node_modules/.bin/ngsw-config dist/my-app ngsw-config.json /my-app/Duration strings support the following units:
s - secondsm - minutesh - hoursd - daysExamples:
"30s" - 30 seconds"15m" - 15 minutes"2h" - 2 hours"7d" - 7 days"1d12h30m" - 1 day, 12 hours, 30 minutesGlob patterns support:
* - Match any characters except path separators** - Match any characters including path separators! - Negate pattern (exclude matching files){} - Brace expansion: {js,css} matches both js and cssExamples:
"/*.js" - All JS files in root"/assets/**" - All files in assets directory"!/**/*.map" - Exclude all source map files"/**/*.{jpg,png}" - All JPEG and PNG images