PWA
Full Progressive Web App support including service worker lifecycle management, install prompts,
caching strategies, and offline-first capabilities. The PWA module communicates with a companion
service worker file (aura-sw.js) via postMessage to configure caching
at runtime. Access everything through Aura.pwa.
Quick Start
Register the service worker, define caching strategies, and handle install prompts in just a few lines.
// 1. Define caching strategies before registering Aura.pwa.addStrategy({ name: 'images', strategy: 'cache-first', match: /\.(png|jpg|webp|svg)$/, maxAge: 7 * 24 * 60 * 60 * 1000 }); // 2. Register the service worker await Aura.pwa.register('/aura-sw.js'); // 3. Precache critical assets Aura.pwa.precache(['/index.html', '/styles.css', '/app.js']); // 4. Handle install prompt Aura.pwa.onInstallPrompt(() => { showInstallBanner(); });
Service Worker Setup
Aura ships with a companion service worker file called aura-sw.js. Place it in your project root (or public directory) so the browser can register it at the top-level scope.
How it works
- The service worker listens for
postMessageevents from the main thread. Aura.pwa.addStrategy()sends aAURA_STRATEGIESmessage with serialized strategy configs.Aura.pwa.precache()sends aAURA_PRECACHEmessage with a list of URLs.Aura.pwa.skipWaiting()sends aSKIP_WAITINGmessage to activate a waiting worker.- On install, the SW precaches any URLs it has received.
- On activate, it cleans up old versioned caches and calls
clients.claim(). - On fetch, it matches the request URL against registered strategies and applies the appropriate caching behavior.
File structure
your-project/ aura-sw.js <-- Service worker (from Aura) index.html app.js <-- Aura.pwa.register('/aura-sw.js') manifest.json
Cache versioning
The service worker uses a CACHE_PREFIX of "aura-cache-" and a CACHE_VERSION of "v1". Each strategy gets its own named cache in the format aura-cache-{name}-v1. Precached assets go into aura-cache-precache-v1. Old caches with the prefix but a different version are automatically deleted on activation.
register()
Register a service worker at the given path. Sends any previously configured strategies to the worker once it activates. Returns the ServiceWorkerRegistration on success, or null if service workers are not supported or registration fails.
| Param | Type | Description |
|---|---|---|
| swPath | string | Path to the service worker file. |
| opts.scope | string? | Scope for the SW registration. Defaults to "/". |
Returns: Promise<ServiceWorkerRegistration | null>
// Basic registration const reg = await Aura.pwa.register('/aura-sw.js'); // With custom scope const reg = await Aura.pwa.register('/sw.js', { scope: '/app/' }); // Guard against unsupported browsers if (reg) { console.log('SW registered', reg.scope); }
unregister()
Unregister the current service worker.
Takes no arguments. Returns true if successfully unregistered, false if no SW was registered.
const success = await Aura.pwa.unregister(); console.log('Unregistered:', success);
onInstallPrompt()
Register a handler for the beforeinstallprompt event. If the event has already fired before this is called, the handler is invoked immediately with the captured event.
| Param | Type | Description |
|---|---|---|
| handler | (e: Event) => void | Callback that receives the beforeinstallprompt event. |
Aura.pwa.onInstallPrompt((e) => { // Show your custom install UI installBanner.style.display = 'flex'; });
promptInstall()
Trigger the native install prompt. Must be called after onInstallPrompt has captured the event. Returns whether the user accepted.
Takes no arguments. Returns true if the user accepted the install, false otherwise.
installBtn.addEventListener('click', async () => { const accepted = await Aura.pwa.promptInstall(); if (accepted) { console.log('App installed!'); installBanner.style.display = 'none'; } });
isStandalone()
Check if the app is currently running in standalone mode (installed PWA). Works on both Chromium and Safari.
Takes no arguments. Returns true if running as an installed PWA.
if (Aura.pwa.isStandalone()) { // Hide browser-specific UI addressBar.style.display = 'none'; console.log('Running as installed PWA'); }
onUpdate()
Listen for service worker updates. The handler fires when a new SW is installed while a previous one is still controlling the page (i.e., an update is available).
| Param | Type | Description |
|---|---|---|
| handler | (reg) => void | Callback that receives the ServiceWorkerRegistration. |
Aura.pwa.onUpdate((reg) => { if (confirm('A new version is available. Reload?')) { Aura.pwa.skipWaiting(); window.location.reload(); } });
checkForUpdate()
Force a service worker update check. Useful for long-lived tabs where you want to periodically check for new versions.
Takes no arguments. Triggers an update check on the current registration.
// Check for updates every 30 minutes setInterval(() => { Aura.pwa.checkForUpdate(); }, 30 * 60 * 1000); // Or check on visibility change document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { Aura.pwa.checkForUpdate(); } });
skipWaiting()
Tell a waiting service worker to activate immediately. Sends a SKIP_WAITING message to the waiting worker. Typically called after the user confirms they want to update.
Takes no arguments. No-ops if there is no waiting worker.
// Activate the new worker and reload Aura.pwa.skipWaiting(); window.location.reload();
addStrategy()
Add a caching strategy that the service worker will apply to matching requests. If the SW is already active, the strategy is sent immediately via postMessage.
CacheStrategy interface
| Property | Type | Description |
|---|---|---|
| name | string | Unique cache name (used as part of the cache key). |
| strategy | string | One of: 'cache-first', 'network-first', 'stale-while-revalidate', 'network-only', 'cache-only'. |
| match | string | RegExp | URL pattern. Strings use includes() matching; RegExp uses .test(). |
| maxAge | number? | Maximum cache age in milliseconds. Only used by cache-first. |
// Cache images aggressively Aura.pwa.addStrategy({ name: 'images', strategy: 'cache-first', match: /\.(png|jpg|webp|gif|svg)$/, maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days }); // API calls: network first with cache fallback Aura.pwa.addStrategy({ name: 'api', strategy: 'network-first', match: '/api/' }); // Static assets: serve stale, update in background Aura.pwa.addStrategy({ name: 'static', strategy: 'stale-while-revalidate', match: /\.(css|js|woff2?)$/ });
precache()
Send a list of URLs to the service worker for precaching. The SW will add them to the aura-cache-precache-v1 cache. Only works after the SW is active.
| Param | Type | Description |
|---|---|---|
| urls | string[] | Array of URLs to precache. |
Aura.pwa.precache([ '/', '/index.html', '/styles.css', '/app.js', '/offline.html', '/icons/logo-192.png' ]);
clearCache()
Delete a specific named cache or all caches. Useful for forcing a fresh start or clearing storage.
| Param | Type | Description |
|---|---|---|
| name | string? | Cache name to delete. If omitted, deletes all caches. |
Returns: true when complete.
// Clear a specific cache await Aura.pwa.clearCache('aura-cache-images-v1'); // Nuclear option: clear everything await Aura.pwa.clearCache();
registration
Getter that returns the current ServiceWorkerRegistration, or null if not registered.
const reg = Aura.pwa.registration; if (reg) { console.log('SW scope:', reg.scope); console.log('Active:', reg.active?.state); }
isSupported
Getter that returns whether the browser supports service workers.
if (Aura.pwa.isSupported) { await Aura.pwa.register('/aura-sw.js'); } else { console.log('Service workers not supported'); }
Caching Strategies Guide
The Aura service worker supports five caching strategies. Choose the right one based on the type of resource and your freshness requirements.
cache-first
Serve from cache if available (and not expired via maxAge). Falls back to network, then caches the response. If both cache and network fail, serves a stale cached version if one exists. Best for static assets that rarely change.
- Use for: images, fonts, icons
- Supports
maxAgefor cache expiration
network-first
Try the network first. If the request succeeds, cache the response. If the network fails, fall back to the cached version. Best for data that should be fresh but must work offline.
- Use for: API responses, dynamic HTML pages
stale-while-revalidate
Return the cached version immediately (if available) while fetching an updated version in the background. The next request will get the fresh data. Best for content where speed matters more than absolute freshness.
- Use for: CSS, JS bundles, frequently accessed pages
network-only
Always go to the network. No caching at all. Best for requests that must never be stale (e.g., authentication, payments).
- Use for: login endpoints, checkout flows, analytics
cache-only
Only serve from cache. Never goes to the network. Returns a 404 if the item is not cached. Best for precached assets that you know will always be available.
- Use for: app shell, offline fallback page
Full example: multi-strategy setup
// Images: cache aggressively for 7 days Aura.pwa.addStrategy({ name: 'images', strategy: 'cache-first', match: /\.(png|jpg|webp|gif|svg|ico)$/, maxAge: 7 * 24 * 60 * 60 * 1000 }); // Fonts: cache first, long expiry Aura.pwa.addStrategy({ name: 'fonts', strategy: 'cache-first', match: /\.(woff2?|ttf|otf|eot)$/, maxAge: 30 * 24 * 60 * 60 * 1000 }); // Static assets: fast but stays updated Aura.pwa.addStrategy({ name: 'static', strategy: 'stale-while-revalidate', match: /\.(css|js)$/ }); // API: fresh data with offline fallback Aura.pwa.addStrategy({ name: 'api', strategy: 'network-first', match: '/api/' }); // Auth: never cache Aura.pwa.addStrategy({ name: 'auth', strategy: 'network-only', match: '/auth/' }); // Register after strategies are configured await Aura.pwa.register('/aura-sw.js'); // Precache the app shell Aura.pwa.precache(['/', '/index.html', '/offline.html']); // Handle updates gracefully Aura.pwa.onUpdate(() => { showToast('Update available — click to refresh'); });