Swoff Swoff

Nuxt

Set up Swoff with Nuxt 3 (client-only mode).

Nuxt

Adapter for Nuxt 3 with client-only mode. Swoff runs client-only — Nuxt server features are not used.

Create Project

npx nuxi@latest init my-app
cd my-app && npm install

Configure Client-Only

// nuxt.config.ts
export default defineNuxtConfig({
  ssr: false, // Required for offline-first
});

Project Structure

my-app
├── plugins
│   └── sw.client.ts
├── swoff
│   ├── sw-template.js
│   ├── sw-generator.js
│   ├── sw-injector.js
│   └── swoff.d.ts
└── package.json

Entry Point (plugins/sw.client.ts)

// plugins/sw.client.ts
export default defineNuxtPlugin(() => {
  if ("serviceWorker" in navigator) {
    window.addEventListener("load", async () => {
      const { version } = await fetch("/version.json").then((r) => r.json());
      await navigator.serviceWorker.register(`/sw-v${version}.js`);
    });
  }
});

Add Patterns

Copy from Patterns:

  1. SW Templateswoff/sw-template.js
  2. Build Scriptswoff/sw-generator.js
  3. Client Registrationswoff/sw-injector.js
  4. TypeScript Declarationsswoff/swoff.d.ts

Output Directory

Nuxt outputs to .output/public/ by default. Update your swoff/sw-generator.js:

writeFileSync(join(__dirname, "..", ".output", "public", `sw-v${pkg.version}.js`), sw);
writeFileSync(join(__dirname, "..", ".output", "public", "version.json"), JSON.stringify({ ... }));

If deploying to Vercel, Netlify, or Cloudflare, the output path may differ.

Update package.json:

{
  "scripts": {
    "build": "nuxt build && node swoff/sw-generator.js"
  }
}

Build & Test

npm version patch
npm run build

Next Steps

On this page