@lunx/plugin-pwa
Zero-config Progressive Web App support. Generates a service worker, web app manifest, and offline cache strategy — making your Lunx app installable and offline-capable.
Installation
bash
npm install --save-dev @lunx/plugin-pwatypescriptlunx.config.ts
import { defineConfig } from 'lunx' import pwa from '@lunx/plugin-pwa' export default defineConfig({ framework: 'react', plugins: [ pwa({ name: 'My Lunx App', shortName: 'LunxApp', description: 'A blazing-fast application built with Lunx', themeColor: '#2563eb', backgroundColor: '#ffffff', display: 'standalone', icons: [ { src: '/icons/pwa-192x192.png', sizes: '192x192', type: 'image/png' }, { src: '/icons/pwa-512x512.png', sizes: '512x512', type: 'image/png' }, { src: '/icons/pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }, ], }), ], })
What gets generated
After running lunx build, the plugin generates:
text
dist/ ├── sw.js # Service worker (auto-registered) ├── manifest.webmanifest # Web app manifest ├── icons/ │ ├── pwa-192x192.png │ └── pwa-512x512.png └── index.html # Updated with manifest and meta tags
Caching strategies
Configure how different resource types are cached. The plugin supports four strategies inspired by Workbox — implemented natively without the Workbox dependency.
typescriptlunx.config.ts
pwa({ name: 'My App', workbox: { // App shell — cache-first for instant loads navigateFallback: '/index.html', navigateFallbackDenylist: [/^\/api\//], // Runtime caching rules (applied in order) runtimeCaching: [ { // API requests — network-first with 5s timeout urlPattern: /^\/api\//, handler: 'NetworkFirst', options: { cacheName: 'api-cache', networkTimeoutSeconds: 5, expiration: { maxEntries: 50, maxAgeSeconds: 300 }, }, }, { // Images — cache-first, serve stale urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp)$/, handler: 'CacheFirst', options: { cacheName: 'image-cache', expiration: { maxEntries: 100, maxAgeSeconds: 30 * 24 * 60 * 60 }, }, }, { // Google Fonts — stale-while-revalidate urlPattern: /^https:\/\/fonts\.googleapis\.com/, handler: 'StaleWhileRevalidate', options: { cacheName: 'google-fonts' }, }, ], }, })
Verifying PWA compliance
bash
# Build and preview lunx build && lunx preview # Open Chrome DevTools → Application → Service Workers # Confirm: sw.js is registered and status is "activated" # Run Lighthouse audit for PWA score npx lighthouse http://localhost:4173 --only-categories=pwa --view
Plugin options
| Field | Type | Default | Description |
|---|---|---|---|
| name | string | — | Full app name shown in OS install prompts and splash screens. |
| shortName | string | — | Short app name (≤12 chars) for home screen icons. |
| themeColor | string | — | Browser chrome color and mobile status bar color. |
| backgroundColor | string | '#ffffff' | Splash screen background color before the app loads. |
| display | string | 'standalone' | Display mode: standalone | fullscreen | minimal-ui | browser. |
| icons | Icon[] | — | Array of icon objects with src, sizes, type, and optional purpose ('maskable'). |
| workbox | WorkboxOptions | — | Fine-grained caching strategy configuration. |
| injectRegister | string | 'auto' | Service worker registration method: auto | script | inline | null. |
Maskable icons
Always provide a
maskable icon variant. Android adaptive icons crop the icon to various shapes — without a maskable variant, the standard icon will be padded with white space, making it look broken on some Android launchers.