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
First of all, THIS WORKS GREAT, AND WE SHOULD PROBABLY GO FORWARD WITH IT EXACTLY AS WRITTEN. It does a good job of adding a new feature to the library without removing anything that already works. The "on" keyword seems superfluous to the developer side of me, but it's small and it reads like English (which is nice) so let's just rock and roll.
Multiple Event Names
I think your spec would automatically handle this, but just to put it out there, we could support swapping in the content on multiple event names by having multiple
swap onstatements. For example:hx-sse="connect /my-url, swap on message, swap on CustomEventName, swap on AnotherEventName"Implementation Notes
The proof of concept included several parts
hx-attributes#1 is simple and would have to be done no matter what.
#2 may not make sense now and should at least be left aside until later.
#3 was harder (for me) than I thought it would be, and was the reason behind our
doSwapfunction that largely duplicates the existing logic in theissueAjaxRequestfunction. This part may be tricky, and it will be good to get @1cg 's expert eyes on it so that we minimize duplication and don't break any existing work.One More Thing
This is probably a discussion for post-1.0, but I'll include it now just because we have some wiggle room with the syntax. The
swap onsyntax seems very "Hyperscript-y" to me and makes me think of future versions of both libraries that are more tightly intertwined.Would there be any reason to use Hyperscript to accomplish this feature, or to use syntax that mirrors Hyperscript more closely? Depending on the solution, it might be a nice reason to use both libraries together. For example:
Again, this is probably a discussion for another day, but I'm starting to think that HTMX and Hyperscript will have enough overlapping use cases that they'll eventually need to become a single intertwined library.
How Can I Help?
I think my two PR's show that this is possible, but they also show me ravaging HTMX's internals to do it. I'm happy to take a first pass at this, but my understanding of the complexities inside HTMX is still lacking. @1cg, if you can point me in a direction I'm happy to run as far as I can, but I don't want to get in your way while I stumble forward.