Server-Sent Events (SSE) & WebSockets Extensions for Real-Time DOM Morphing
- Last updated
- Prerequisites:
- Server-Sent Events (`EventSource`)
- WebSocket protocol basics
- htmx
- sse
- websockets
- real-time
- streaming
- extensions
Read at your depth
The practical view
HTMX supports real-time updates via official extensions: `sse.js` and `ws.js`. For Server-Sent Events: `<div hx-ext="sse" sse-connect="/events" sse-swap="message">`. The element connects to the SSE stream and swaps incoming HTML payloads directly into the DOM. For WebSockets: `<div hx-ext="ws" ws-connect="/chat">` allows both receiving HTML pushes and sending form payloads over the WebSocket connection (`ws-send`).
The same idea in other frameworks
Socket.io / standard WebSocket hook updating React state arrays.RxJS `webSocket()` subject emitting to component signals.VueUse `useWebSocket()` composable.`<div hx-ext="sse" sse-connect="/live" sse-swap="chatMessage">`.Legacy vs modern
Manual WebSocket JSON Listener vs Declarative HTMX WS Extension
Manual WebSockets require state parsing and element creation; HTMX WS extensions swap streamed HTML directly into the target.
ws.onmessage = (e) => { const { msg } = JSON.parse(e.data); append(msg); }; // ❌ Client template plumbing<div hx-ext="sse" sse-connect="/chat-feed" sse-swap="new_message" hx-swap="beforeend"> // ✅ NEWInterview gotchas
Context
Interviewers test your knowledge of the SSE wire protocol and HTMX integration.
The mechanical answer
The server must format responses according to the W3C SSE standard with an event name and HTML data string. For example: ```http event: new_message data: <div class="chat-bubble">Hello World!</div> ``` The `event:` name matches `sse-swap="new_message"`, and the `data:` contains the raw HTML fragment to swap.
Trap
SSE messages require two trailing newline characters (`\n\n`) to flush the event over the HTTP stream.
Context
Checks understanding of multi-target updates in real-time streams.
The mechanical answer
Yes. A single SSE or WebSocket push event can contain both the main HTML fragment and multiple elements with `hx-swap-oob="true" id="..."`. HTMX will update the main target and simultaneously update all matching OOB elements across the entire page.
Trap
Ensure OOB elements sent over WebSockets have unique IDs that match existing DOM elements on the client.