Swoff Swoff

Build Scripts

Generate versioned SW + version.json from your package.json.

Prerequisite: You've created swoff/sw-template.js from the SW Template pattern. This script reads that template and generates versioned output.

Quick Setup

Confirm SW Template Exists

You created swoff/sw-template.js in the previous step. If not, see SW Template first.

Create Build Script

Create swoff/sw-generator.js:

swoff/sw-generator.js
import { readFileSync, writeFileSync, readdirSync, existsSync, mkdirSync } from "fs";
import { fileURLToPath } from "url";
import { join, dirname, relative } from "path";

const __dirname = dirname(fileURLToPath(import.meta.url));
const pkg = JSON.parse(readFileSync(join(__dirname, "package.json"), "utf8"));
const template = readFileSync(join(__dirname, "swoff/sw-template.js"), "utf8");

const outputDir = join(__dirname, "dist");
if (!existsSync(outputDir)) mkdirSync(outputDir, { recursive: true });

function collectAssets(dir) {
  const entries = readdirSync(dir, { withFileTypes: true });
  const assets = [];
  for (const entry of entries) {
    const fullPath = join(dir, entry.name);
    if (entry.isDirectory()) {
      assets.push(...collectAssets(fullPath));
    } else {
      assets.push("/" + relative(outputDir, fullPath));
    }
  }
  return assets;
}

const allAssets = collectAssets(outputDir);
const swFile = `sw-v${pkg.version}.js`;
const assetsToCache = allAssets
  .filter((a) => a !== "/" + swFile && a !== "/version.json")
  .map((url) => ({ url, options: {} }));

let sw = template.replace(
  "// [[CACHE_NAME]]",
  `CACHE_NAME = 'sw-v${pkg.version}'`,
);
sw = sw.replace("// [[ASSETS_LIST]]", `ASSETS_TO_CACHE = ${JSON.stringify(assetsToCache, null, 2)}`);

writeFileSync(join(outputDir, swFile), sw);
const config = JSON.parse(readFileSync(join(__dirname, "swoff.config.json"), "utf8"));

writeFileSync(
  join(outputDir, "version.json"),
  JSON.stringify({
    version: pkg.version,
    minSupportedVersion: config.minSupportedVersion || "0.0.0",
    generatedAt: new Date().toISOString(),
  }),
);

Important: The dist path above is the default. Your framework may use a different output directory (e.g., .output, .next/export, build). See your framework guide for the correct path.

Update package.json

Append the sw generating script at the end of the build script in package.json.

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

Add TypeScript Declarations (optional)

If you use TypeScript, create swoff/swoff.d.ts. See Utilities.

Build & Test

npm version patch
npm run build

Test offline: DevTools → Application → Service Workers → Check "Offline".

Next Steps

On this page