ワンクリックで
service-worker-updates
Guide for modifying service worker caching. Edit sw-template.js (not sw.js), run yarn prebuild after changes.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Guide for modifying service worker caching. Edit sw-template.js (not sw.js), run yarn prebuild after changes.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | service-worker-updates |
| description | Guide for modifying service worker caching. Edit sw-template.js (not sw.js), run yarn prebuild after changes. |
Guide for modifying the service worker caching strategy. Prevent common mistakes that break offline functionality.
The public/sw.js file is generated and will be overwritten.
Always edit: public/sw-template.js
public/sw-template.js → scripts/generate-sw.mjs → public/sw.js
(source) (build script) (generated)
The build script:
sw-template.js{{API_ORIGIN}} placeholder with NEXT_PUBLIC_API_URL originpublic/sw.jsRun yarn prebuild after changing sw-template.js:
# After editing sw-template.js
yarn prebuild
# Or just run dev (includes prebuild)
yarn dev
Note: yarn build alone does NOT run prebuild. Environment-specific builds (build:development|staging|production) do include it.
// public/sw-template.js
const API_ORIGIN = "{{API_ORIGIN}}"; // Replaced at build time
// Workbox 7 configuration
importScripts(
"https://storage.googleapis.com/workbox-cdn/releases/7.0.0/workbox-sw.js"
);
const { registerRoute } = workbox.routing;
const { CacheFirst, NetworkFirst, StaleWhileRevalidate } = workbox.strategies;
// Cache strategies for different routes
registerRoute(
({ url }) => url.origin === API_ORIGIN && url.pathname.startsWith("/api/"),
new NetworkFirst({ cacheName: "api-cache" })
);
| Strategy | Use Case | Example |
|---|---|---|
CacheFirst | Static assets, images | Fonts, icons |
NetworkFirst | API calls, dynamic data | Events, news |
StaleWhileRevalidate | Balance freshness/speed | Category lists |
// public/sw-template.js
// Add new route
registerRoute(
({ url }) => url.pathname.startsWith("/new-feature/"),
new StaleWhileRevalidate({
cacheName: "new-feature-cache",
matchOptions: { ignoreVary: true }, // REQUIRED for Next.js App Router
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
}),
],
})
);
yarn prebuild
yarn dev
# Check DevTools > Application > Service Workers
registerRoute(
({ url }) => url.origin === API_ORIGIN && url.pathname.includes("/events"),
new NetworkFirst({
cacheName: "events-cache",
networkTimeoutSeconds: 3,
matchOptions: { ignoreVary: true }, // REQUIRED for Next.js App Router
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 100,
maxAgeSeconds: 60 * 60, // 1 hour
}),
],
})
);
registerRoute(
({ request }) => request.destination === "image",
new CacheFirst({
cacheName: "images-cache",
matchOptions: { ignoreVary: true }, // REQUIRED for Next.js App Router
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
}),
],
})
);
// Offline page fallback
workbox.routing.setCatchHandler(async ({ event }) => {
if (event.request.destination === "document") {
return caches.match("/offline");
}
return Response.error();
});
The {{API_ORIGIN}} placeholder is replaced with the origin from NEXT_PUBLIC_API_URL:
# .env
NEXT_PUBLIC_API_URL=https://api.example.com/v1
# Results in sw.js:
const API_ORIGIN = "https://api.example.com";
ignoreVary: trueNext.js App Router adds Vary headers (rsc, next-router-state-tree, next-router-prefetch, etc.) to responses. Without ignoreVary: true, service worker cache matching fails because these headers differ between request types (RSC navigation vs client fetch vs direct load).
Note: This addresses Workbox service worker cache matching, not the underlying Next.js dynamic route issue (which relates to Cache-Control: private/no-store when Server Components call headers() or cookies()). The ignoreVary: true option allows the SW to treat the same URL as one cache entry regardless of Vary header differences.
Always add matchOptions with ignoreVary: true:
new workbox.strategies.StaleWhileRevalidate({
cacheName: "my-cache",
matchOptions: {
ignoreVary: true, // REQUIRED for Next.js App Router compatibility
},
plugins: [
/* ... */
],
});
Without this, the same URL may be fetched multiple times and cached as separate entries, causing:
ignoreVary: true → Cache misses due to Next.js Vary headerssw-template.js (not sw.js)?yarn prebuild after changes?matchOptions: { ignoreVary: true } to strategies?Guide for adding environment variables. Use when adding new env vars to ensure all 5 locations are updated (code, env files, Coolify, workflow, GitHub secrets).
Enforce the internal API proxy layer pattern. Use when adding API endpoints, fetching data from backend, implementing HMAC signing, or working with lib/api/* or app/api/*.
Best practices for React 19 and Next.js 16 App Router. Use when creating components, hooks, or pages. Enforces server-first rendering, proper client boundaries, and modern React patterns.
MANDATORY checklist before writing ANY new code. Use this skill FIRST before implementing any feature, component, utility, type, or hook. Enforces DRY principle and existing pattern reuse.
Evaluate external PR suggestions (Gemini, CodeRabbit) against project conventions. Use when asked to review or agree with external code review comments.
Guide for CSP, security headers, and external scripts. Use fetchWithHmac for APIs, safeFetch for external services.