Manifest and Icons
The manifest option
Section titled “The manifest option”Instead of a separate manifest.json file, vite-plugin-pwa lets you define the manifest directly in vite.config.ts. The plugin injects it into every HTML page and adds the necessary <link rel="manifest"> tag automatically. This keeps your PWA configuration in one place alongside the rest of your Vite setup.
Defining the manifest in vite.config.ts
Section titled “Defining the manifest in vite.config.ts”import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({ plugins: [ react(), VitePWA({ registerType: 'prompt', includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'robots.txt'], manifest: { name: 'My PWA App', short_name: 'MyApp', description: 'A Progressive Web App built with Vite and React', theme_color: '#ffffff', background_color: '#ffffff', display: 'standalone', start_url: '/', icons: [ { src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png', }, { src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png', }, { src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable', }, ], }, }), ],});includeAssets
Section titled “includeAssets”The includeAssets option tells Workbox to precache static files that are NOT automatically part of the build output. Without it, files like favicon.ico and apple-touch-icon.png — which you place manually in public/ — would not be included in the service worker’s precache manifest.
includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'robots.txt'],Adding these here ensures they are cached on the first service worker install, so the browser and iOS home screen always serve them from cache even when the user is offline.
Icon generation with @vite-pwa/assets-generator
Section titled “Icon generation with @vite-pwa/assets-generator”Instead of manually exporting every icon size from a design tool, you can generate all required sizes from a single SVG source using the @vite-pwa/assets-generator package.
npx @vite-pwa/assets-generator --preset minimal logo.svgThis command reads logo.svg from the current directory and writes all the generated PNG icons into public/. The minimal preset produces the sizes that cover the icons array shown above.
apple-touch-icon and favicon
Section titled “apple-touch-icon and favicon”The 180x180 apple-touch-icon.png file must be placed in public/ so Vite copies it into dist/ during the build. iOS uses this image when a user adds your app to their home screen. Reference it in includeAssets so Workbox precaches it.
The favicon.ico file follows the same rule — it lives in public/ and should be listed in includeAssets.
Icon size reference
Section titled “Icon size reference”| Icon size | Purpose |
|---|---|
| 192x192 | Standard Android home screen |
| 512x512 | Splash screen / install prompt |
| 512x512 maskable | Adaptive icon on Android |
| 180x180 | Apple Touch Icon (iOS home screen) |
Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
| Define the manifest through vite-plugin-pwa’s config | Generates multiple icon sizes automatically, no manifest.json file to maintain by hand | Tied to the plugin’s specific config syntax, one more option surface to learn |
Write a static manifest.json yourself | Direct control, no plugin abstraction in the way | You maintain every icon size and keep it in sync with the build entirely by hand |
Common mistakes
Section titled “Common mistakes”- Providing only a single icon size in the config, so the plugin cannot generate the full set Android/iOS expect.
- Forgetting to set the base path to match the real deployment target, breaking icon paths in the manifest at production build time.
- Not generating a separate maskable icon, so the icon gets clipped oddly on Android as if nothing had been configured at all.
The Vite PWA ecosystem is used by real projects like Elk, the open-source Mastodon client, which generates its manifest and full icon set from a single vite-plugin-pwa config (Elk’s package.json lists vite-plugin-pwa), and many VitePress sites use the same plugin to make their documentation installable with barely any manifest code of their own.