Presence
Same API as the core createPresence plugin, but backed by Redis hashes. Presence state is shared across instances with cross-instance join/leave notifications via Redis pub/sub.
When to use over the built-in plugin: The core presence plugin only knows about connections on the local process. If a user connects to instance A, instance B has no idea they are online. The Redis presence extension gives you a single, consistent view of who is online across all instances, with per-entry TTLs so stale entries from crashed instances expire automatically.
Setup
// src/lib/server/presence.js
import { redis } from './redis.js';
import { createPresence } from 'svelte-adapter-uws-extensions/redis/presence';
export const presence = createPresence(redis, {
key: 'id',
select: (userData) => ({ id: userData.id, name: userData.name }),
heartbeat: 30000,
ttl: 90
}); Usage
// src/hooks.ws.js
import { presence } from '$lib/server/presence';
export async function subscribe(ws, topic, { platform }) {
await presence.join(ws, topic, platform);
}
export async function close(ws, { platform }) {
await presence.leave(ws, platform);
} Options
| Option | Default | Description |
|---|---|---|
key | 'id' | Field for user dedup (multi-tab) |
select | strips __-prefixed keys | Extract public fields from userData |
heartbeat | 30000 | TTL refresh interval in ms |
ttl | 90 | Per-entry expiry in seconds. Entries from crashed instances expire individually after this period, even if other instances are still active on the same topic. |
API
| Method | Description |
|---|---|
join(ws, topic, platform) | Add connection to presence |
leave(ws, platform, topic?) | Remove from a specific topic, or all topics if omitted |
sync(ws, topic, platform) | Send list without joining |
list(topic) | Get current users |
count(topic) | Count unique users |
clear() | Reset all presence state |
destroy() | Stop heartbeat and subscriber |
hooks | { subscribe, close } - ready-made WebSocket hooks |
Zero-config hooks
Instead of writing subscribe and close handlers manually, destructure presence.hooks:
// src/hooks.ws.js
import { presence } from '$lib/server/presence';
export const { subscribe, close } = presence.hooks; subscribe handles both regular topics (calls join) and __presence:* topics (calls sync so the client gets the current list). close calls leave.
If you need custom logic (auth gating, logging), wrap the hooks:
import { presence } from '$lib/server/presence';
export async function subscribe(ws, topic, ctx) {
if (!ctx.platform.getUserData(ws).authenticated) return;
await presence.hooks.subscribe(ws, topic, ctx);
}
export const { close } = presence.hooks; Was this page helpful?