sdx_realtime
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_engine - 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.