pwa-deployment
Deploying first-aid-reference as a PWA on various platforms. Use when you need to deploy to Netlify, Vercel, a static server, or Docker; configure the service worker cache strategy; handle app updates; or troubleshoot PWA installation and caching issues. Triggers include "deploy PWA", "service worker", "cache strategy", "app update", "install prompt", "offline not working", or any deployment-related task for first-aid-reference.
Best use case
pwa-deployment is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Deploying first-aid-reference as a PWA on various platforms. Use when you need to deploy to Netlify, Vercel, a static server, or Docker; configure the service worker cache strategy; handle app updates; or troubleshoot PWA installation and caching issues. Triggers include "deploy PWA", "service worker", "cache strategy", "app update", "install prompt", "offline not working", or any deployment-related task for first-aid-reference.
Teams using pwa-deployment should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/pwa-manager/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How pwa-deployment Compares
| Feature / Agent | pwa-deployment | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Deploying first-aid-reference as a PWA on various platforms. Use when you need to deploy to Netlify, Vercel, a static server, or Docker; configure the service worker cache strategy; handle app updates; or troubleshoot PWA installation and caching issues. Triggers include "deploy PWA", "service worker", "cache strategy", "app update", "install prompt", "offline not working", or any deployment-related task for first-aid-reference.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# pwa-deployment
Deploy and maintain first-aid-reference as a Progressive Web App. Covers service worker configuration, cache strategy, update handling, and platform-specific deployment.
## Build output
After `pnpm build`, the `dist/` folder contains:
```
dist/
index.html
sw.js # Service worker (generated by Workbox)
manifest.webmanifest # PWA manifest
registerSW.js # SW registration helper
assets/
index-[hash].js # Main bundle
index-[hash].css # Styles
articles-[hash].json # All guide content
categories-[hash].json # Category metadata
icons/
pwa-192x192.png
pwa-512x512.png
```
## Service worker configuration
The service worker is generated by `vite-plugin-pwa` using Workbox `generateSW` strategy. Configuration is in `vite.config.ts`:
```typescript
VitePWA({
registerType: 'autoUpdate',
workbox: {
globPatterns: ['**/*.{js,css,html,json,png,svg}'],
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-cache',
expiration: { maxEntries: 10, maxAgeSeconds: 60 * 60 * 24 * 365 },
},
},
],
},
manifest: {
name: 'first-aid-reference',
short_name: 'First Aid',
theme_color: '#0891b2',
background_color: '#fafaf9',
display: 'standalone',
icons: [
{ src: 'icons/pwa-192x192.png', sizes: '192x192', type: 'image/png' },
{ src: 'icons/pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'any maskable' },
],
},
})
```
## Cache strategy
All static assets (JS, CSS, HTML, JSON, images) are precached on service worker install using `CacheFirst`. This means:
1. On first visit: all assets downloaded and cached
2. On subsequent visits: assets served from cache instantly
3. Background: service worker checks for updates; new assets downloaded to a waiting SW
4. Update: when user closes and reopens the app, the new SW activates and updates the cache
## Handling updates
`registerType: 'autoUpdate'` means the new service worker activates automatically without user prompting. The app reloads with fresh content on next launch.
To show an "update available" toast instead of auto-reload, change to `registerType: 'prompt'` and handle the `needRefresh` event from `useRegisterSW`:
```typescript
import { useRegisterSW } from 'virtual:pwa-register/react';
const { needRefresh, updateServiceWorker } = useRegisterSW({
onRegistered(r) { console.log('SW registered:', r); },
onRegisterError(error) { console.error('SW registration error:', error); },
});
// Show a banner when needRefresh[0] is true
// Call updateServiceWorker(true) to reload and activate
```
## Deploying to Netlify
1. Build: `pnpm build`
2. Deploy: `netlify deploy --prod --dir=dist`
Required `public/_headers` file for security headers:
```
/*
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
```
Required `public/_redirects` file for SPA routing:
```
/* /index.html 200
```
## Deploying to Vercel
1. Push to GitHub
2. Connect repo in Vercel dashboard
3. Set build command: `pnpm build`
4. Set output directory: `dist`
Or CLI:
```bash
pnpm add -g vercel
vercel --prod
```
Add `vercel.json` for SPA routing and headers:
```json
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" }
]
}
]
}
```
## Deploying with Docker
```dockerfile
FROM node:20-alpine AS build
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
`nginx.conf`:
```nginx
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
# SPA routing
location / {
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
# Cache static assets aggressively
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Do not cache service worker or manifest
location ~ \.(webmanifest|sw\.js)$ {
expires -1;
add_header Cache-Control "no-store";
}
}
```
## Deploying to a static server
The `dist/` folder is a self-contained static site. Any static file server works:
```bash
# npx serve
npx serve dist -p 8080 --single
# Python 3
cd dist && python3 -m http.server 8080
# Node http-server
npx http-server dist -p 8080 --spa
```
Note: for offline to work correctly, the service worker must be served over HTTPS or localhost.
## Verifying offline capability
1. `pnpm build && pnpm preview`
2. Open `http://localhost:4173` in Chrome
3. Open DevTools > Application > Service Workers - confirm SW is registered and activated
4. Open DevTools > Network - enable "Offline" checkbox
5. Reload the page - app should load fully from cache
6. Navigate to any article - should load instantly without network
## Troubleshooting
**Service worker not registering**
- Must be served over HTTPS or localhost
- Check browser console for registration errors
- Verify `registerSW.js` is included in the build
**Content not updating after deploy**
- The SW uses cache-first strategy - users see old content until the new SW activates
- With `registerType: 'autoUpdate'`, the new SW activates on next app launch
- Force update: Clear Site Data in DevTools > Application > Storage
**PWA install prompt not appearing**
- Requires HTTPS
- Requires a valid manifest with icons
- Chrome requires a user gesture interaction before showing the prompt
- iOS Safari does not support the install prompt - show manual instructions instead
**Cache size too large**
- The default `globPatterns` includes all build output
- Exclude large files by adding to `globIgnores` in workbox config
- Use `runtimeCaching` for large assets with size limitsRelated Skills
deployment-tracker
Track every deployment event via CLI or REST API. Searchable web dashboard with service timelines, rollback tracking, and per-service deploy tokens.
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.
Skill: personal-finance
## Overview
Skill: csv-import
## Overview
Skill: Syntax Highlighting
## Purpose