How to Set Up PWA Functionality with the Docusaurus PWA Plugin: Complete Implementation Guide
The @docusaurus/plugin-pwa package transforms any Docusaurus site into a Progressive Web App by injecting PWA head tags, registering a Workbox-based service worker, and implementing configurable offline mode activation strategies.
The facebook/docusaurus repository maintains the official PWA plugin that enables offline documentation browsing and installable app experiences. By configuring the plugin in docusaurus.config.js, you enable service worker precaching, custom activation logic, and PWA-compliant manifest injection without writing boilerplate service worker code.
Installing the Docusaurus PWA Plugin
Add the plugin to your project using your package manager of choice.
yarn add @docusaurus/plugin-pwa
# or
npm install @docusaurus/plugin-pwa
Once installed, register the plugin in your docusaurus.config.js file. The plugin accepts a configuration object that defines offline behavior, debug settings, and head tag injection.
// docusaurus.config.js
module.exports = {
// ... existing config
plugins: [
[
'@docusaurus/plugin-pwa',
{
debug: false,
offlineModeActivationStrategies: [
'appInstalled',
'standalone',
'queryString',
],
pwaHead: [
{
tagName: 'link',
rel: 'manifest',
href: '/manifest.webmanifest',
},
{
tagName: 'meta',
name: 'theme-color',
content: '#0d47a1',
},
],
},
],
],
};
Core Architecture and Source Files
The plugin architecture consists of five key components implemented in packages/docusaurus-plugin-pwa/src/:
options.ts— Defines the configuration schema and default values forofflineModeActivationStrategies,injectManifestConfig, andpwaHead. This file validates yourdocusaurus.config.jsoptions at build time.registerSw.ts— Runs in the browser to register the service worker usingworkbox-window. It reads environment variables (PWA_SERVICE_WORKER_URL,PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES,PWA_DEBUG) to determine when to activate offline mode.sw.ts— The actual service worker implementation that usesworkbox-precachingto cache assets. It handlesinstall,activate,fetch, andmessageevents, and executes custom logic fromswCustomif provided.renderReloadPopup.tsx— Dynamically imports and renders thePwaReloadPopupcomponent when a new service worker is waiting, prompting users to reload for updates.plugin-pwa.d.ts— Provides TypeScript type definitions forPluginOptionsand configuration interfaces.
Offline Mode Activation Strategies
The plugin supports seven activation strategies defined in options.ts. When any enabled strategy returns true, the service worker precaches assets and enables offline functionality.
| Strategy | Activation Condition |
|---|---|
appInstalled |
Site is installed as a PWA (detected via appinstalled event or navigator.getInstalledRelatedApps). |
standalone |
Page runs in standalone display mode (window.matchMedia('(display-mode: standalone)')). |
queryString |
URL contains ?offlineMode=true for debugging purposes. |
mobile |
Browser viewport width is ≤ 996 pixels. |
saveData |
User's connection has the saveData flag enabled. |
always |
Unconditionally enables offline mode. |
| Default combination | By default, the plugin uses appInstalled, queryString, and standalone. |
Configure these in your plugin options array:
offlineModeActivationStrategies: ['standalone', 'appInstalled', 'mobile']
Creating the Web App Manifest
While optional, a Web App Manifest is required for installable PWA functionality. Create a manifest.webmanifest file in your static directory:
// static/manifest.webmanifest
{
"name": "My Docusaurus Site",
"short_name": "Docs",
"start_url": ".",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ffffff",
"icons": [
{
"src": "/img/logo.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
Reference this manifest in your pwaHead configuration using the tagName: 'link' with rel: 'manifest' as shown in the configuration example above.
Advanced Customization
Custom Service Worker Logic
For additional caching rules or background sync, provide a custom service worker file via the swCustom option. The plugin imports your default export and invokes it with {offlineMode, debug} parameters.
// docusaurus.config.js
{
swCustom: require.resolve('./src/custom-sw.js'),
}
// src/custom-sw.js
export default function ({offlineMode, debug}) {
if (debug) {
console.log('[CustomSW] Running with offlineMode:', offlineMode);
}
if (offlineMode) {
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/')) {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
}),
);
}
});
}
}
Customizing the Reload Popup
Override the default update notification UI by swizzling the theme component:
npx docusaurus swizzle @docusaurus/theme-classic PwaReloadPopup
This copies the component to src/theme/PwaReloadPopup/index.tsx where you can modify the JSX and styling:
import React from 'react';
import Translate from '@docusaurus/Translate';
import styles from './styles.module.css';
export default function PwaReloadPopup({onReload}) {
return (
<div className={styles.popup}>
<p>
<Translate id="pwa.reloadMessage">
A new version is available.
</Translate>
</p>
<button onClick={onReload}>
<Translate id="pwa.reloadButton">Update Now</Translate>
</button>
</div>
);
}
The plugin automatically detects and uses your swizzled component through renderReloadPopup.tsx.
Fine-Tuning Precaching with Workbox
Control precaching behavior through injectManifestConfig, which accepts standard Workbox InjectManifest options:
{
injectManifestConfig: {
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB
exclude: [/\.map$/, /admin\//],
},
}
Summary
- Install the plugin via
yarn add @docusaurus/plugin-pwaand register it indocusaurus.config.js. - Configure activation strategies like
appInstalled,standalone, oralwaysto control when offline mode activates based on the logic inregisterSw.ts. - Provide PWA head tags including manifest links and theme colors to satisfy PWA requirements.
- Customize behavior by pointing
swCustomto a JavaScript file for additional service worker logic, or swizzlePwaReloadPopupto change the update UI. - Verify functionality using Chrome DevTools Application panel to inspect the service worker registration and cached assets.
Frequently Asked Questions
What does the Docusaurus PWA plugin do?
The plugin converts your static Docusaurus site into a Progressive Web App by generating a service worker (via sw.ts) that precaches build assets, injecting required <meta> and <link> tags into the document head, and managing offline mode activation through configurable strategies defined in options.ts.
How do I enable offline mode in Docusaurus?
Offline mode is controlled by the offlineModeActivationStrategies array in your plugin configuration. Set this to ['always'] to enable it unconditionally, or use conditional strategies like 'appInstalled' or 'standalone' to activate only when the user has installed the PWA or is running it as a standalone app.
Can I customize the service worker in Docusaurus PWA?
Yes. Use the swCustom configuration option to point to a JavaScript file exporting a default function. The plugin executes this function inside the service worker context with offlineMode and debug parameters, allowing you to add custom fetch handlers, background sync, or additional caching logic alongside the default Workbox precaching.
How do I test if my Docusaurus PWA is working correctly?
Run yarn start or yarn build followed by yarn serve to test the production build. Open Chrome DevTools, navigate to Application > Service Workers, and verify that sw.js is registered. Check the Cache Storage section for precached assets, and use the Network panel to simulate offline mode to confirm that pages load without a connection.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →