SDX Realtime
This module enables server-driven, real-time updates for Drupal. It allows components to automatically re-render when their underlying data changes, using either WebSockets or Server-Sent Events without requiring custom JavaScript for simple cases. It also provides frameworks for handling events, presence, and data synchronization, with adapters for popular JavaScript frameworks.
SDX Realtime turns any Single Directory Component into a live, server-driven surface. Three submodules - sdx_reactive, sdx_websocket, sdx_broadcast - bring the patterns you'd otherwise reach for Livewire, Hotwire, Phoenix LiveView, or Pusher to do, and they speak Drupal natively. Mount a component, declare a few cache tags or a channel, and the UI re-renders the moment the underlying entity, config, or message changes server-side. No custom JavaScript required for the simple cases; full TypeScript hooks for the complex ones.
Built on top of the SDX ecosystem, every realtime feature is framework-agnostic at the core and ships first-party adapters for React, Vue, and Svelte.
Features
- Server-driven reactive components (sdx_reactive). Write a PHP plugin with
#[SdxReactive], declare state with#[ReactiveState], expose handlers with#[ReactiveAction], derive values with#[Computed], react to entity / config events with#[OnEvent]. The framework owns DOM morphing, debouncing, and HMAC-signed state checksums; you write zero JavaScript. - Bidirectional WebSocket channels with presence (sdx_websocket). Pure-PHP RFC 6455 server (no Node, no Ratchet) with channel pub/sub, automatic reconnect with exponential backoff, presence tracking, and HMAC handshake authentication. Drush command starts it as a long-running process.
- SSE broadcast (sdx_broadcast). Server-Sent Events for one-way push (notifications, tickers, live feeds). Optional automatic entity-CRUD broadcast on the
entity.{type}channel. - Auto-live DataProviders. Opt in once (
broadcast_cache_tags: true) and every Drupalcache_tags.invalidator->invalidateTags(...)call fans through an SSE channel. Components subscribe withuseLiveDataProvider(props, { tags, refetchUrl })and re-render the moment any of their declared dependencies change. - First-party TypeScript hooks for every framework.
useChannel,usePresence,useBroadcast,useCacheTags,useLiveDataProvider- identical contracts across React, Vue, and Svelte, all importable from@sdx/*aliases the SDX build pipeline auto-resolves. - Sensible defaults. Cache-tag broadcasting is opt-in; sensitive tags (
user:*,session,permissions:*,config:user.role.*) ship blocklisted by default to avoid information disclosure. - Examples included.
collab-notepad(WS + presence),live-feed(SSE),live-counter(auto-live DataProvider), and reactive-only counterparts insdx_examples_reactive.
Post-Installation
Each submodule installs cleanly with no required configuration. Enable only what you need:
composer require drupal/sdx_realtime drush en sdx_reactive sdx_websocket sdx_broadcast drush sdx:resolve # picks up the new *.sdx.yml manifests
sdx_reactive works out of the box. Place any reactive component in a render array; the pre-render hook does the rest. Configuration lives at Configuration › Development › SDX › Reactive.
sdx_websocket needs the WebSocket server running. Start it as a long-lived process under your supervisor of choice (systemd, supervisord, Forever, ...):
drush sdx:ws --host=0.0.0.0 --port=8080Configure the public URL clients connect to under Configuration › Development › SDX › WebSocket. The page-attachments hook auto-injects the URL and per-session HMAC token into drupalSettings.
sdx_broadcast exposes /api/sdx-broadcast/stream/{channel} for SSE consumption. To enable cache-tag fan-out (the auto-live DataProvider feature):
drush cset sdx_broadcast.settings broadcast_cache_tags 1Fine-tune the blocklist via sdx_broadcast.settings:cache_tags_blocklist if your site emits tags you don't want on the wire.
Once a submodule is enabled, its @sdx/* aliases auto-register and become importable from any SDX component:
import { useLiveDataProvider } from '@sdx/live-data-provider/react'; const live = useLiveDataProvider(props, { tags: [`node:${props.nid}`], refetchUrl: window.location.pathname, });
Additional Requirements
- SDX
^1 || ^2- the framework SDX Realtime extends. - Drupal core
^10.3 || ^11. - sdx_reactive additionally requires sdx_react (the React framework module shipped with SDX).
- sdx_websocket needs PHP with the
socketsextension and a process supervisor of your choice. No Node, no Ratchet, no ReactPHP - the server is pure-PHP RFC 6455. - sdx_broadcast works with PHP-FPM, mod_php, or any SAPI that lets a request hold an open response (most do).
Recommended modules/libraries
- sdx_react, sdx_vue, sdx_svelte - the framework adapters that make the realtime hooks idiomatic in your component code.
- sdx_drast - the SDX theme engine that renders DataProvider envelopes consumed by
useLiveDataProvider. - sdx_router - SPA navigation; pairs naturally with realtime updates so navigations feel instant.
- A reverse proxy that supports HTTP/1.1 keep-alive for SSE and WebSocket upgrades (nginx, Caddy, HAProxy, Apache 2.4+ with mod_proxy_wstunnel).
Similar projects
- Mercure / Pusher / Ably integrations. External-service patterns. SDX Realtime keeps the data plane on your own infrastructure and integrates with Drupal's cache-tag system natively, so reactivity follows entity lifecycle without per-channel wiring.
- Drupal Refreshless / partial reloads. Useful for navigation-style updates; SDX Realtime targets continuous per-component reactivity, including DM-style bidirectional channels and presence.
- Laravel Livewire / Rails Hotwire / Phoenix LiveView. Closest cousins outside Drupal.
sdx_reactivebrings the same PHP-attribute pattern (state + actions + computed properties + event subscriptions) to Drupal, andsdx_broadcast+useLiveDataProvidergive you the cache-tag-driven reactivity Drupal's render system makes possible but no other framework has.
Community Documentation
Documentation site, walkthrough videos, and a public demo are in flight. Until they land, the best starting point is the sdx_examples_realtime submodule - three working components (collab-notepad, live-feed, live-counter) that exercise every hook the framework ships.
The CHANGELOG.md in the repository tracks every API addition with usage snippets, and the per-module *.sdx.yml manifests show up in drush sdx:doctor alongside core SDX so you can see what's enabled at a glance.