Real-Time Updates Reference
Real-time updates in SveltyCMS: Server-Sent Events (SSE) for event streaming and Yjs collaboration for concurrent editing — both adapter-node compatible.
On this page
Note: SveltyCMS ships real-time on adapter-node-compatible transports — no uWebSockets dependency. Two mechanisms are production-wired:
- Server-Sent Events (SSE) —
GET /api/content/events(aliasGET /api/events) streams EventBus events (content updates, cache invalidation, settings changes) to connected clients over plain HTTP.- Yjs collaborative editing — CRDT sync for concurrent field editing via
collaboration-service(SSE transport) with an optional native WebSocket server on/ws(yjs-sync-server, wired inindex.cjs).
GraphQL queries and mutations remain HTTP-based (POST /api/graphql). There is no GraphQL-over-WebSocket subscriptions endpoint in the current release — use the SSE event stream or Yjs collaboration for live updates.
⚡ Quick Reference
| Feature | Details |
|---|---|
| SSE endpoint | GET /api/content/events (alias GET /api/events) |
| Collaboration (SSE) | collaboration-service + SseProvider (client) + yjs-service (server) |
| Collaboration (WebSocket) | ws://[domain]/ws via yjs-sync-server (production index.cjs entry) |
| Protocol | text/event-stream + y-protocols over Yjs |
| Auth Methods | Session cookie (SSE); session cookie / headers at the handshake layer (WS) |
| GraphQL over WS | ❌ Not shipped — use SSE / Yjs |
1. The Goal
Maintain a live, reactive UI (collaborative editor, real-time dashboard, settings sync) that updates instantly when content is modified by other users or background jobs — a superior, type-safe alternative to polling.
2. Server-Sent Events (SSE)
Server side
handleContentEventsStream (src/routes/api/[...path]/handlers/content.ts) subscribes to the internal EventBus (@utils/event-bus) and pushes normalized, tenant-filtered payloads to the client:
content:update→content_updatecache:invalidate→cache_invalidateconfig:change→config_changesettings:update→settings_update(consumed byglobal-settings.svelte.ts)- Keep-alive pings every 30s; buffered micro-flushes every 32ms.
Client side
// Subscribe to the global event stream (browser)
const events = new EventSource("/api/content/events", { withCredentials: true });
events.onmessage = (e) => {
const data = JSON.parse(e.data);
if (data.type === "content_update") {
// invalidate loaders / refetch structure
}
};
Built-in consumers: content-sse.svelte.ts, global-settings.svelte.ts, sse-provider.svelte.ts.
3. Yjs Collaborative Editing
Transport
- Default (SSE): the client
SseProvider(src/services/collaboration/sse-provider.svelte.ts) connects to/api/eventsfor pushed updates andGET/POST /api/collaboration/yjsfor full-state sync / batched updates. Server state lives inyjs-service(src/services/collaboration/yjs-service.ts), keyed bydocId+ tenant. - Optional WebSocket:
yjs-sync-server(src/services/collaboration/yjs-sync-server.ts) attaches aws-based sync server to the HTTP server at/ws(y-protocols wire format, tenant-awaretenantId:docIdkeys). Wired in the production entryindex.cjs.
Wiring
fields.svelte integrates collaborationService (src/services/collaboration/collaboration-service.svelte.ts) when a collection has collaboration.enabled: true — field changes are pushed into the Yjs document and merged back on remote updates, with awareness (cursor presence) per editor.
4. Architecture (Server-Side)
Performance & Security
- Standard Node.js
wsengine for the/wscollaboration server — no native addons, deployable on any cloud/Docker platform. - Tenant isolation: SSE filters by
locals.tenantId; WS sync keys documents astenantId:docId. - Zero runtime deps for SSE — plain HTTP
ReadableStreamresponses, no extra packages.