Server Push
Real-time cache invalidation from the Service Worker via SSE or WebSocket.
If you're coming from Socket.io for real-time updates: Swoff's server push connects to your SSE or WebSocket endpoint from the Service Worker, not from the page. The connection survives navigation, tab refresh, and doesn't consume page memory. When the server sends tags, the SW invalidates cached responses across all tabs — no need to manually wire up socket events to cache invalidation. See the GraphQL & Push architecture.
Preconditions
- Swoff initialized with data fetching enabled and
tagInvalidationconfigured - Cookie auth required — bearer and custom auth are incompatible (the SW has no DOM to refresh tokens)
- A server endpoint that sends SSE events or WebSocket messages
Status
Disabled by default. Server push must be explicitly enabled.
Enable
npx @swoff/cli add server-pushOr set config manually:
{
"features": {
"serverPush": {
"enabled": true,
"type": "sse",
"endpoint": "/api/events",
"reconnectDelayMs": 5000
}
}
}Generated files
| File | What it does | Import in your code? |
|---|---|---|
swoff/server-push/client.ts | SSE/WS connection manager (runs in SW, no page imports needed) | No — auto-managed by SW |
swoff-api.bundle.js | startPushEvents(), stopPushEvents(), isPushConnected() on window.swoff for no-bundler projects | No (auto-initializes) |
No page-side imports needed for bundler projects — the SW connects to your endpoint on activation and manages reconnection. For no-bundler projects, the swoff-api.bundle.js exposes swoff.startPushEvents() / swoff.stopPushEvents() / swoff.isPushConnected() to control the server-push connection from the page.
Usage
Server sends tags for invalidation
// SSE event data or WebSocket message:
{
"tags": ["notes", "users:456"]
}The SW receives this and calls invalidateByTags(["notes", "users:456"]). All tabs re-fetch the affected data on their next fetchWithCache call.
Multiple tags per event
{
"tags": ["notes", "dashboard", "stats:*"]
}Supports glob patterns — stats:* invalidates all cache entries under any stats:* tag.
Connection lifecycle
The SW manages:
- Auto-connect on SW activation
- Reconnect with exponential backoff (respects
reconnectDelayMs) - Connection survives navigation and tab refresh
- Connection drops when the SW is terminated (browser idle) — re-established on next navigation or push
Customize
Connection parameters are config-only. No generated files to edit.
To customize reconnection behavior, adjust reconnectDelayMs in config. The SW doubles the delay on each failure, capped by the initial value.
Config
{
"features": {
"tagInvalidation": {},
"serverPush": {
"enabled": true,
"type": "sse",
"endpoint": "/api/events",
"reconnectDelayMs": 5000
}
}
}type—"sse"(Server-Sent Events) or"websocket"endpoint— URL of your server push endpointreconnectDelayMs— initial reconnect delay; doubles on each failure (capped at this value)
Framework adapters
Server push invalidates cache entries in the SW, which dispatches cache-invalidated to all clients — the same event consumed by useSwoffFetch. The flow:
Server sends tags via SSE/WS
→ SW calls invalidateByTags(tags)
→ SW invalidates matching cache entries
→ SW broadcasts cache-invalidated to all tabs
→ Your adapter re-fetches affected dataEvent:
| Event | Detail shape | Purpose |
|---|---|---|
cache-invalidated | { tags } | SW invalidated entries — refetch data whose URL tags intersect |
The adapter pattern is identical to the one described in the Tag Invalidation guide — the only difference is the source of invalidation (server push instead of manual calls). See the Blueprint for the event reference and adapter patterns.
Important: tagInvalidation is required
Server push works by calling invalidateByTags() in the SW. The tagInvalidation configuration object must be present in your config for tags to be generated and invalidated. Server push requires tag invalidation to be active.
SSE vs WebSocket
| Aspect | SSE | WebSocket |
|---|---|---|
| Direction | Server → client only | Bidirectional |
| Reconnection | Built-in (EventSource API) | Manual (Swoff handles it) |
| Payload | Text only | Text or binary |
| Browser support | All modern browsers | All modern browsers |
| When to use | Simple push from server | Need 2-way communication |