Setting Up @vite-pwa/astro
Setting up @vite-pwa/astro
Section titled “Setting up @vite-pwa/astro”@vite-pwa/astro is an Astro integration built on top of Vite PWA. It wires a service worker and a web app manifest directly into Astro’s build pipeline, so you get full PWA support with almost no manual configuration. Because Astro is an SSG framework, the integration pre-caches your built output automatically — pages, scripts, stylesheets, and assets are all available offline right after the first visit.
Installation
Section titled “Installation”Install the package with your preferred package manager:
npm install -D @vite-pwa/astro# orpnpm add -D @vite-pwa/astroAdding the integration
Section titled “Adding the integration”Open astro.config.mjs and add AstroPWA to the integrations array:
import { defineConfig } from 'astro/config'import AstroPWA from '@vite-pwa/astro'
export default defineConfig({ integrations: [ AstroPWA({ registerType: 'autoUpdate', manifest: { name: 'My Astro PWA', short_name: 'AstroPWA', theme_color: '#ffffff', icons: [ { src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png' }, { src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png' }, ], }, workbox: { globPatterns: ['**/*.{css,js,html,svg,png,ico}'], }, devOptions: { enabled: true, }, }), ],})registerType
Section titled “registerType”registerType controls how the service worker handles updates when a new version is deployed.
'autoUpdate'— The service worker installs and activates silently in the background. Users always get the latest version without seeing any prompt.'prompt'— The service worker waits for your code to confirm the update. Usevirtual:pwa-registerto present a “reload to update” button to the user.
import { registerSW } from 'virtual:pwa-register'registerSW({ immediate: true })Import src/pwa.ts in your root layout to activate the registration logic on every page.
manifest option
Section titled “manifest option”The manifest object is injected as a <link rel="manifest"> tag and served as manifest.webmanifest. Fill in at minimum name, short_name, theme_color, and icons. The integration validates the manifest at build time and will warn you about missing required fields.
workbox vs injectManifest
Section titled “workbox vs injectManifest”By default, @vite-pwa/astro uses the workbox strategy, which generates a complete service worker for you. The workbox.globPatterns array tells Workbox which built files to add to the precache manifest — ['**/*.{css,js,html,svg,png,ico}'] covers all common static asset types.
If you need full control over your service worker logic — custom routing, background sync, push handling — switch to the injectManifest strategy:
AstroPWA({ strategies: 'injectManifest', srcDir: 'src', filename: 'sw.ts', manifest: { /* ... */ },})With injectManifest, you write your own src/sw.ts. At build time, Vite PWA compiles it and injects the precache manifest list into it. You get both flexibility and automatic precaching.
devOptions
Section titled “devOptions”By default, the service worker is disabled in the Vite dev server because hot-module replacement and a caching SW do not mix well. Set devOptions.enabled: true to register the SW during development so you can verify offline behaviour and manifest metadata without running a production build first.
AstroPWA({ // ...other options devOptions: { enabled: true, },})Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
Use the full @vite-pwa/astro package | Sets up service worker + manifest in one step, plugs straight into Astro’s build pipeline | Ties you to the Vite PWA ecosystem, you have to keep the plugin updated yourself |
| Configure the service worker manually in Astro | Not tied to a specific plugin, full control | You must integrate with Astro’s build output entirely by hand, risking bugs from asset hashes falling out of sync |
Common mistakes
Section titled “Common mistakes”- Forgetting to turn on
devOptions.enabled: true, so the service worker cannot be tested on the dev server at all, leading to a false impression that the setup is broken. - Not realizing Astro defaults to SSG, so precaching only really happens at build time — testing in dev mode and being confused about why nothing is cached.
- Setting
registerTypeto the wrong value for the intended UX (e.g.autoUpdatewhen you actually wanted a user-facing prompt), so the update experience does not match what was designed.
@vite-pwa/astro is part of the same Vite PWA ecosystem that Elk, the open-source Mastodon client, uses on its own stack (Elk’s package.json lists vite-plugin-pwa), and many VitePress and Astro documentation sites use the same kind of setup to become installable in just a few lines of config.