Skip to content

Configuring the Web App Manifest

The web app manifest is a JSON file that tells the browser how to present your PWA — its name, icons, launch URL, and display mode. With the @astrojs/pwa (vite-plugin-pwa) integration you never write that file by hand. You declare everything inside astro.config.mjs and the integration emits the manifest and links it automatically.

Pass a manifest key to AstroPWA(). Every standard manifest field is supported:

astro.config.mjs
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',
description: 'A PWA built with Astro',
theme_color: '#ffffff',
background_color: '#ffffff',
display: 'standalone',
start_url: '/',
icons: [
{ src: 'pwa-64x64.png', sizes: '64x64', type: 'image/png' },
{ src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png' },
{ src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'any' },
{ src: 'maskable-icon-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
],
},
pwaAssets: {
image: 'public/logo.svg',
},
}),
],
});

Key properties explained:

  • name — The full application name shown on splash screens and app stores.
  • short_name — A shorter label used when space is limited (home-screen icon label).
  • description — A sentence describing the app; used by some app stores.
  • theme_color — Tints the browser’s address bar or the OS title bar to match your brand.
  • background_color — The background of the splash screen shown while the app loads.
  • display — Controls how much browser UI is visible (see table below).
  • start_url — The URL the OS opens when the user launches the installed PWA.
  • icons — An array of image descriptors. The browser picks the most appropriate size.

The purpose field matters:

  • "any" — a standard icon used in most contexts (app drawers, home screen on iOS/macOS).
  • "maskable" — an icon whose subject is contained inside a “safe zone” so Android can apply its adaptive-icon mask (circle, squircle, etc.) without clipping your artwork.

Providing both ensures your icon looks correct on every platform.

At build time the integration writes a manifest.webmanifest file to the output root. Its contents mirror what you declared:

{
"name": "My Astro PWA",
"short_name": "AstroPWA",
"description": "A PWA built with Astro",
"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", "purpose": "any" },
{ "src": "maskable-icon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}

The integration also automatically injects a <link rel="manifest" href="/manifest.webmanifest"> tag into every page’s <head> — you do not need to add it yourself.

Generating icons automatically with pwaAssets

Section titled “Generating icons automatically with pwaAssets”

Manually resizing icons to every required dimension is tedious. The pwaAssets option (powered by @vite-pwa/assets-generator) generates all icon variants from a single source image:

pwaAssets: {
image: 'public/logo.svg', // SVG or high-res PNG source
},

Point it at your logo.svg and the generator produces pwa-64x64.png, pwa-192x192.png, pwa-512x512.png, maskable-icon-512x512.png, and more — no manual resizing needed.

The display field controls how much browser chrome is shown when the PWA is launched as an installed app:

displayBehaviour
standaloneApp-like window, no browser UI
minimal-uiMinimal browser UI
fullscreenFull screen, no UI
browserRegular browser tab

"standalone" is the most common choice for PWAs because it gives the experience of a native app without the browser address bar.

OptionBenefitCost
Configure the manifest through astro.config.mjs (@vite-pwa/astro)Manifest is generated automatically at build time, always in sync with one configHave to learn Astro-specific plugin options instead of just writing plain JSON
Put manifest.json directly in public/You can see and edit the file directly, no config abstraction in the wayMust sync it by hand with the build output yourself, risking a manifest that does not match the real assets
  • Setting scope/start_url that does not match the actual deployed base path (e.g. deploying to a sub-path but leaving start_url as "/").
  • Not generating icons through the plugin, so icon sizes fall short of what stores/Android expect.
  • Forgetting that a config change always needs a rebuild — it does not hot-reload the way normal component code does.

Astro’s own documentation site uses @vite-pwa/astro to configure its manifest through config so it stays in sync with the build pipeline automatically, and many VitePress sites take the same config-driven approach so thousands of documentation sites can install as a PWA without hand-writing a manifest.json.

Where do you configure the web app manifest when using the AstroPWA integration?
What does the integration automatically add to every page's <head>?
Why should you provide both a "any" and a "maskable" 512x512 icon?
Which display mode gives an app-like window with no browser UI?