SwoffSwoff

Push Notifications

Subscribe, notify, unsubscribe, and framework adapters for push notification management.

If you've worked with the Web Push API directly, Swoff provides the browser-side subscription management and SW push event handler — you just need a server endpoint to send the subscription and trigger pushes.

Preconditions

  • Swoff initialized with a registered service worker
  • A server endpoint to store subscriptions and send push events (VAPID keys required)

Status

Disabled by default. Push notifications must be explicitly enabled.

Enable

npx @swoff/cli add push-notification

Or set features.pushNotifications: true in swoff.config.json then regenerate.

Generated files

FileWhat it doesImport in your code?
swoff/push-notification/index.tsrequestNotificationPermission(), subscribeToPush(), unsubscribeFromPush(), isSubscribed(), getPushSubscription()Yes (bundler only)
swoff/sw/template.jsPush event handler — receives push events, displays notificationsNo (built into SW)
swoff-api.bundle.jsSame push API via window.swoff.subscribeToPush() etc. for no-bundler projectsNo (auto-initializes)

Usage

Bundler projects

import {
  requestNotificationPermission,
  subscribeToPush,
  unsubscribeFromPush,
  isSubscribed,
  getPushSubscription,
} from "./swoff/push-notification";

// Step 1: request permission (user gesture required)
const granted = await requestNotificationPermission();
if (!granted) return;

// Step 2: subscribe — returns PushSubscription
const subscription = await subscribeToPush();
// Send subscription to your server:
await fetch("/api/push/subscribe", {
  method: "POST",
  body: JSON.stringify(subscription.toJSON()),
});

// Step 3: check status
const sub = await getPushSubscription();
const subscribed = await isSubscribed();

// Step 4: unsubscribe
await unsubscribeFromPush();
await fetch("/api/push/unsubscribe", { method: "POST" });

No-bundler projects

Include the auto-initializing bundles, then call the API on window.swoff:

<script src="/swoff/client-injector.bundle.js"></script>
<script src="/swoff/swoff-api.bundle.js"></script>
<script>
  swoff.configure({ push: { vapidPublicKey: "YOUR_VAPID_PUBLIC_KEY" } });

  const granted = await swoff.requestNotificationPermission();
  if (!granted) return;

  const subscription = await swoff.subscribeToPush();
  await fetch("/api/push/subscribe", {
    method: "POST",
    body: JSON.stringify(subscription.toJSON()),
  });

  const subscribed = await swoff.isSubscribed();
  await swoff.unsubscribeFromPush();
</script>

Framework adapters

This section has one adapter:

useSwoffPush

Exposes push state: { subscribed, permission, subscribe, unsubscribe }.

Events listened to:

EventDetail shapePurpose
push-subscription-changed{ subscribed }Push subscription added or removed
push-permission-changed{ permission }Notification permission granted or denied

If your framework already has a useSwoffPush adapter (React, Vue, Svelte), the CLI generates it into swoff/adapters/. To create adapters for any other framework, see the Blueprint for the event reference and adapter patterns.

Server side (example)

The generated SW handles incoming push events and displays notifications. Your server sends push messages via the Web Push protocol:

// Server code (any language)
await webpush.sendNotification(
  subscription,
  JSON.stringify({
    title: "New Note",
    body: "Someone shared a note with you",
    icon: "/icon-192.png",
    data: { url: "/notes/123" },
  }),
);

Customize

The push event handler is embedded in the generated SW (swoff/sw/template.js). It parses the push payload and calls self.registration.showNotification(). To customize notification appearance or behavior, edit the push event section in the template.

Config

{
  "features": {
    "pushNotifications": true
  }
}
  • pushNotifications — enable push subscription management and SW push handler

The VAPID public key is set at runtime via swoff.configure({ push: { vapidPublicKey: "..." } }) for no-bundler projects, or directly in swoff/push-notification/index.ts for bundler projects. Generate a key pair with npx web-push generate-vapid-keys.

On this page