webapp-astro-pwa
A ready-to-use Astro component library for adding Progressive Web App (PWA) support to your Astro projects. This package provides drop-in components and utilities for manifest injection, service worker registration, install prompts, and more. Fully suppor
A ready-to-use Astro component library for adding Progressive Web App (PWA) support to your Astro projects. This package provides drop-in components and utilities for manifest injection, service worker registration, install prompts, and more. Fully support Astro 4
Boost your Astro projectβs performance and user experience by enabling Progressive Web App (PWA) features. With WebApp Astro PWA, your site loads faster, works offline, and can be installed directly to usersβ devicesβjust like a native app.
- Faster Load Times: Assets are cached for instant loading, even on slow or unreliable networks.
- Offline Support: Your app remains accessible and functional without an internet connection.
- Installable Experience: Users can add your app to their home screen for quick access, increasing engagement and retention.
- Native-like Feel: Deliver a seamless, app-like experience with push notifications, background sync, and more.
Empower your Astro project with PWA capabilities and stand out with a modern, high-performance web app!
- Easy PWA Integration: Add PWA support to any Astro project with minimal setup.
- Customizable Install UI: Includes install button, popover, and installation messages.
- Manifest & Meta Tags: Auto-injects manifest and meta tags from config.
- Service Worker: Bundles and registers a Workbox-powered service worker.
-
Configurable Strategies: Choose caching strategies and assets via
pwa.config.json
. - TypeScript Support: Fully typed for safer integration.
Your project will include the following files and folders:
/
βββ index.ts
βββ src/
β βββ PWA.astro
β βββ PWABtn.astro
β βββ PWASetupWindow.astro
β βββ types.ts
β βββ manifest_imgs/
β βββ pwa/
β βββ bundle-sw.mjs
β βββ index.ts
β βββ PoweredWebAppBuilder.ts
β βββ setup.js
β βββ sw.js
β βββ utilities.ts
β βββ workbox.config.cjs
β βββ view/
β βββ PopoverSupport.ts
β βββ components/
β β βββ InstallationMessage.astro
β β βββ InstallationPage.astro
β β βββ InstallBtn.astro
β β βββ MetaServiceWorker.astro
β β βββ ServiceWorkerRegistration.astro
β βββ utils/
β βββ EventHandler.ts
β βββ PWAInstallPrompt.ts
β βββ PWASetup.ts
β βββ utilities.ts
βββ pwa.config.json
βββ package.json
βββ setup.js
βββ README.md
npm install webapp-astro-pwa
After install, the setup script will automatically add a generateAndBundleSW
script to your project's package.json
.
To enable PWA features across your entire Astro app, import the PWA
component and place it inside your main layoutβs <head>
section. This will inject the manifest, meta tags, and register the service worker automatically.
---
// new code added
import { PWA } from "webapp-astro-pwa";
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>Astro Basics</title>
<!-- new code added -->
<PWA />
</head>
Next Open your astro.config.mjs
(or astro.config.ts
) at your astro project and add the following
// filepath: astro.config.mjs
import { defineConfig } from "astro/config";
// new code added
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
// new code added
PoweredWebAppBuilder({}),
...
],
});
Next, build your application using the command:
npm run dev
This will generate the service worker file at / βββ src/ βββ ap/ βββ sw.js
enabling your app to function as a web app with offline capabilities (even if itβs not yet installable as a PWA still you don't have manifest file). By default, files will be stored in the browserβs Cache Storage under the name static-assets. You can change this name in the configuration to manage cache versions and control how assets are cached and updated. This approach gives you flexibility and full control over your appβs offline experience.
// filepath: astro.config.mjs
import { defineConfig } from 'astro/config';
// new code added
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
// this line changed
PoweredWebAppBuilder({
"cacheAssets": "static-assets_v2",
}),
...
]
});
Important:
When your application is running as a PWA, you may sometimes need to remove and re-add the service worker file (sw.js
) for changes to take effect. Browsers aggressively cache service workers, so after making updates to your service worker or its configuration, clear the old service worker or unregister it to ensure users receive the latest version.
Force update of service worker file default false
// filepath: astro.config.mjs
import { defineConfig } from 'astro/config';
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
PoweredWebAppBuilder({
// this line changed
"forceUpdate": true,
}),
...
]
});
You can also choose a file fetching strategy for your PWA. Available options are: CacheFirst
, CacheOnly
, NetworkFirst
, NetworkOnly
, and StaleWhileRevalidate
(the default is StaleWhileRevalidate
).
For more details about these strategies, see the Workbox documentation.
// filepath: astro.config.mjs
import { defineConfig } from 'astro/config';
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
// this line changed
PoweredWebAppBuilder({
"strategy": "CacheFirst",
}),
...
]
});
-
"disableDevLogs": true
β enables or disables Workbox logs in the console. Set totrue
to turn off Workbox logging, orfalse
to see Workbox logs during development. Defaulttrue
// filepath: astro.config.mjs
import { defineConfig } from 'astro/config';
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
// this line changed
PoweredWebAppBuilder({
"disableDevLogs": false,
}),
...
]
});
You can extend your service worker with additional custom scripts using the scripts
option in your astro.config.mjs
(or astro.config.ts
). This allows you to modularize your service worker logicβfor example, to add push notifications, analytics, or custom caching strategiesβby importing extra files via importScripts
.
Add a scripts
array to your PoweredWebAppBuilder
configuration. Each entry should be a path (relative to your project root or public/
) to a JavaScript file you want to include in the service worker.
// filepath: astro.config.mjs
import { defineConfig } from "astro/config";
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
PoweredWebAppBuilder({
// ...other options...
scripts: [
"http://example.com/src/assets/js.js/custom-sw-script.js",
"http://example.com/src/assets/js.js/analytics-sw.js",
],
}),
],
});
All scripts listed will be injected at the top of your generated sw.js
using importScripts
:
// In the generated sw.js
importScripts(
"http://example.com/src/assets/js.js/custom-sw-script.js",
"http://example.com/src/assets/js.js/analytics-sw.js"
);
// ...rest of the service worker code...
Tip: Use this feature to keep your service worker code clean and maintainable by splitting advanced logic into separate files.
To make your Astro project installable as a Progressive Web App (PWA) and automatically generate a manifest file during build, update your astro.config.mjs
(or astro.config.ts
) as follows:
-
isManifest: true
β ensures the manifest is used - defaultfalse
. -
createManifest: true
β instructs the builder to generate the manifest file - defaultfalse
. -
manifestPath: "manifest.json"
β specifies the path where the manifest will be created - defaultmanifest.json
. -
manifest
β the basic manifest info. -
icons
β table of icons for add to component in head.
Add the following to your configuration for minimal PWA support:
// filepath: astro.config.mjs
import { defineConfig } from "astro/config";
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
PoweredWebAppBuilder({
isManifest: true,
createManifest: true,
manifestPath: "manifest.json",
manifest: {
name: "My PWA Example",
short_name: "PWAExample",
description: "A simple Progressive Web App example.",
start_url: "/",
display: "standalone",
theme_color: "#8936FF",
icons: [
{
sizes: "512x512",
src: "node_modules/webapp-astro-pwa/src/manifest_imgs/icon512x512.png",
type: "image/png",
},
{
sizes: "192x192",
src: "node_modules/webapp-astro-pwa/src/manifest_imgs/icon192x192.png",
type: "image/png",
},
],
},
icons: [
{
rel: "icon",
type: "png",
sizes: "512x512",
href: "/webapp-astro-pwa/src/manifest_imgs/icon512x512.png",
},
{
rel: "apple-touch-icon",
type: "png",
sizes: "192x192",
href: "/webapp-astro-pwa/src/manifest_imgs/icon512x512.png",
},
],
}),
],
});
- Enables installation of your app as a PWA on supported devices.
- Automatically generates the manifest file at the specified path after building your project.
- **Injects basic manifest and icons.
After updating your configuration, rebuild your application. The manifest file will be created automatically, and your app will be ready for installation as a PWA.
For a complete PWA experience and optimal support on all platforms, add the following meta tags to your configuration. These tags improve installability, appearance, and integration on both Android and iOS devices:
// filepath: astro.config.mjs
import { defineConfig } from "astro/config";
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
PoweredWebAppBuilder({
isManifest: true,
createManifest: true,
manifestPath: "manifest.json",
manifest: {
name: "My PWA Example",
short_name: "PWAExample",
description: "A simple Progressive Web App example.",
start_url: "/",
display: "standalone",
theme_color: "#8936FF",
icons: [
{
sizes: "512x512",
src: "node_modules/webapp-astro-pwa/src/manifest_imgs/icon512x512.png",
type: "image/png",
},
{
sizes: "192x192",
src: "node_modules/webapp-astro-pwa/src/manifest_imgs/icon192x192.png",
type: "image/png",
},
],
},
icons: [
{
rel: "icon",
type: "png",
sizes: "512x512",
href: "/webapp-astro-pwa/src/manifest_imgs/icon512x512.png",
},
{
rel: "apple-touch-icon",
type: "png",
sizes: "192x192",
href: "/webapp-astro-pwa/src/manifest_imgs/icon512x512.png",
},
],
// ...table with mete information ...
meta: [
{
name: "mobile-web-app-capable",
content: "yes",
},
{
name: "apple-mobile-web-app-capable",
content: "yes",
},
{
name: "application-name",
content: "PWAExample",
},
{
name: "apple-mobile-web-app-title",
content: "PWAExample",
},
{
name: "theme-color",
content: "#8936FF",
},
{
name: "msapplication-navbutton-color",
content: "#8936FF",
},
{
name: "apple-mobile-web-app-status-bar-style",
content: "black-translucent",
},
{
name: "viewport",
content: "width=device-width, initial-scale=1, shrink-to-fit=no",
},
{
name: "msapplication-starturla",
content: "/",
},
],
}),
],
});
To enable extra installation prompts, add the following to your configuration:
-
isInstallBtnVisible: true
β ensures the additional installation is used - defaultfalse
.
// filepath: astro.config.mjs
import { defineConfig } from 'astro/config';
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
export default defineConfig({
integrations: [
// this line changed
PoweredWebAppBuilder({
"isInstallBtnVisible": true,
}),
...
]
});
There are two options for displaying the install prompt:
Popup Modal: Use to show a modal that blocks the page until the user interacts with the install prompt. Simple Button: Use to add a standalone install button anywhere in your app.
Note: Not all browsers support the PWA install prompt. For unsupported browsers, a notification will be shown with instructions to install the PWA using the standard browser menu.
Import and use the main components in your Astro pages/layouts:
---
import { PWA, PWABtn, PWASetupWindow } from "webapp-astro-pwa";
---
<PWA /> <!-- Injects manifest/meta and registers service worker -->
<PWASetupWindow
title="Install Our App"
description="Get the best experience by installing our app."
btnText="Install"
btnBackground="#4361ee"
background="#fff"
hideSvg={false}
/>
Or, for a simple install button:
<PWABtn btnText="Install App" btnBackground="#3a0ca3" hideSvg={false} />
You can easily enable web push notifications in your Astro PWA project using the notification
option in the PoweredWebAppBuilder
configuration. This allows your application to request user permission for push notifications and manage subscriptions for web push messages.
Add the following options to your astro.config.mjs
(or astro.config.ts
):
import { defineConfig } from "astro/config";
import PoweredWebAppBuilder from "webapp-astro-pwa/pwa";
// https://astro.build/config
export default defineConfig({
integrations: [
PoweredWebAppBuilder({
notification: true, // Enables web push notifications (default: false)
saveSubscriptionPath: "path_to_server_for_save_subscription", // API endpoint to save push subscriptions
applicationServerKey: "key_client_side", // VAPID public key for push notifications
}),
],
});
-
notification: Set to
true
to enable web push notifications. By default, this isfalse
. When enabled, your app will request user permission to receive push notifications and handle push subscription logic. -
saveSubscriptionPath: The server endpoint where user push subscriptions will be sent and stored. This should point to your backend API that manages push subscribers.
-
applicationServerKey: The VAPID public key used for authenticating push messages on the client side. This key is required for subscribing users to push notifications.
Note:
Make sure your backend is set up to handle and store push subscriptions at the specified saveSubscriptionPath
, and that you generate a valid VAPID key pair for secure push messaging.
With these options enabled, your PWA will be ready to request notification permissions and manage web push subscriptions, allowing you to send real-time updates directly to your users. Thanks to this option, you can send simple web push notifications with an icon, body, title, and URL.
Edit pwa.config.json
at the root of your project to customize manifest, icons, meta tags, caching strategy, and more.
Example:
{
"isInstallBtnVisible": true,
"createManifest": true,
"cacheAssets": "static-assets",
"disableDevLogs": true,
"isManifest": true,
"manifestPath": "manifest.json",
"strategy": "CacheFirst",
"manifest": {
/* ... */
},
"icons": [
/* ... */
],
"meta": [
/* ... */
]
}
-
PWA
: Injects manifest/meta and registers the service worker. -
PWABtn
: Standalone install button. -
PWASetupWindow
: Full install popover with customizable UI.
To (re)generate and bundle your service worker, run:
npm run generateAndBundleSW
This uses Workbox and your config to inject the manifest and bundle the service worker to public/sw.js
.
Type definitions for configuration and component props are available in src/types.ts
.
MIT
Feel free to open issues or PRs for improvements and bug fixes.