The current SSE implementation is geared towards triggering events in the DOM, requiring an HTTP request to be sent up to get new content:
<div hx-sse="connect /event_stream">
<div hx-get="/chatroom" hx-trigger="sse:chatter">
...
</div>
</div>In this case, an SSE event named chatter would trigger a GET to the /chatroom URL.
This is a very limited use of the Server Sent Events API. In particular, there are two aspects of SSE that are ignored:
- SSE events can have data (not just names) associated with them
- SSE events do not need to have a name (i.e. they can be pure data-only messages)
I propose the following extensions to the current SSE functionality:
If an element wants to directly swap the data of a message into its body, I propose the following syntax:
<div hx-sse="connect /event_stream">
<div hx-sse="swap on chatter">
...
</div>
</div>The swap on indicates that this element wants to listen for chatter messages and swap the body when they occur.
The hx-swap attribute can then be used to determine exactly how the swap is done, as with normal swaps.
In the case of a data-only message, the message type is message according to the SSE spec. Thus, the form swap on message should work the same as the named event implementation.
<div hx-sse="connect /event_stream">
<div hx-sse="swap on message">
...
</div>
</div>We should support both connecting and listening for an event (or events) in the same hx-sse declaration, by
allowing comma separated values:
<div hx-sse="connect /event_stream, swap on message">
...
</div>These two changes would be relatively modest, but I think would address the major shortcomings of the current SSE behavior without requiring a large code refactor. With these changes SSE is on equal, or perhaps greater footing than WebSockets as a way to achieve dynamic web UI within the declarative model.
Another nice aspect of this proposal is that the features are additive, which means that SSE improvments, which I very much wnat to see implemented, would not be a blocker to an htmx 1.0 release.
- MDN SSE Article - https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
- SSE Spec - https://html.spec.whatwg.org/multipage/server-sent-events.html
- Initial SSE improvement PR - bigskysoftware/htmx#155
- Second SSE improvement PR - bigskysoftware/htmx#185
I've just committed an update to this branch. I think it meets the spec provided by @1cg. I'm trying to avoid cluttering the HTMX repository with PRs, so just let me know when I should post it into the HTMX repo.
All of the changes from the previous commit are in the processSwap function. It removes @tomberek 's
doSwapfunction in favor of inlining code from the WebSockets implementation. These changes are consolidated into the commented section beginning on line 846. The comments are just placeholders for now, and should probably be removed once this branch lands on dev.I'm still concerned that commas in URLs could break this in ways that are difficult to troubleshoot. Also, (though less important for now) is that this code doesn't implement some other features that are common in other parts of HTMX -- specifically
hx-settle, which would be very useful for highlighting new content that is added into the DOM. Is there an easy way to just abstracthx-settleinto something we could call from here?