Skip to content

Conversation

@scriptogre
Copy link

@scriptogre scriptogre commented Aug 16, 2025

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

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

@netlify
Copy link

netlify bot commented Aug 16, 2025

Deploy Preview for htmx-extensions canceled.

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

@AdamVig
Copy link

AdamVig commented Oct 6, 2025

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.

@scriptogre
Copy link
Author

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

The sse-swap attribute now defaults to "message" only when an element has
  sse-connect but no sse-swap AND no nested sse-swap elements. This preserves
  the common pattern of using parent elements as containers for multiple
  sse-swap children without conflicting message event listeners.
@scriptogre
Copy link
Author

scriptogre commented Oct 6, 2025

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

@scriptogre scriptogre changed the title Default to message event for sse-swap SSE Extension: Default sse-swap="message"` to keep setup simple Oct 14, 2025
@scriptogre scriptogre changed the title SSE Extension: Default sse-swap="message"` to keep setup simple SSE Extension: Default sse-swap="message" to keep setup simple Oct 14, 2025
@scriptogre
Copy link
Author

This PR would also make #180 more neat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants