htmx-extensions icon indicating copy to clipboard operation
htmx-extensions copied to clipboard

SSE Extension: Default `sse-swap="message"` to keep setup simple

Open scriptogre opened this issue 5 months ago • 5 comments

Summary

I wish this minimal setup just worked™:

<div sse-connect="/events">Loading…</div>
data: <span>I'm an unnamed event!</span>

Expectation: Payload from data: swaps directly into <div sse-connect=...> (using default swap strategy innerHTML).

Reality: Unnamed events are ignored, unless you add sse-swap="message" to sse-connect element.

Why?

I understand browsers treat unnamed SSE events as message by default, but with this change we could:

  1. Match the extension's default with the browser's default
  2. Match the extension's behaviour with the behavior of hx-get/hx-post (where hx-target="this" is implicit)
  3. Remove the gotcha & keep simple scenarios simple.

Implementation

Add sse-swap="message" by default on the sse-connect element (unless there's any nested sse-swap attributes).

Edge Cases

Nested swaps

The pattern of using nested sse-swap attributes should continue to work (default is not applied in this scenario).

<div sse-connect="/events">
  <div sse-swap="foo"></div>
  <div sse-swap="bar"></div>
</div>

Triggering Server Callbacks

The pattern of triggering server callbacks should continue to work normally because the default message listener only catches unnamed events.

<div hx-ext="sse" sse-connect="/event_stream">
    <div hx-get="/chatroom" hx-trigger="sse:chatter">
        ...
    </div>
</div>

Htmx version: 2.0.6 Used extension(s) version(s): 2.2.2

Checklist

  • [x] I have read the contribution guidelines
  • [x] I ran the test suite locally (npm run test) and verified that it succeeded

scriptogre avatar Aug 16 '25 20:08 scriptogre

Deploy Preview for htmx-extensions canceled.

Name Link
Latest commit 1caf3a1bf14ae9f1d54ea42d4202a3f9fd61dcc2
Latest deploy log https://app.netlify.com/projects/htmx-extensions/deploys/68e3f60db2b53d00081ec7d0

netlify[bot] avatar Aug 16 '25 20:08 netlify[bot]

Would this work for multiple nested sse-swaps, like this?

<div sse-connect="/events">
  <div sse-swap="foo"></div>
  <div sse-swap="bar"></div>
</div>

I'm wondering if this pull request would implicitly add sse-swap="message" to the parent <div>, which I think would break this pattern.

AdamVig avatar Oct 06 '25 15:10 AdamVig

That's a very good concern! Thanks for catching that for me. Let me test it out and see.

scriptogre avatar Oct 06 '25 15:10 scriptogre

The latest commit should handle it gracefully. I also added an explicit test for the scenario you described.

scriptogre avatar Oct 06 '25 17:10 scriptogre

This PR would also make #180 more neat.

scriptogre avatar Oct 15 '25 09:10 scriptogre