Skip to content

Comments

feat(ws): handle non-JSON messages as raw HTML with cancelable event#3641

Merged
1cg merged 2 commits intobigskysoftware:fourfrom
stukennedy:ws-raw-message-handling
Jan 29, 2026
Merged

feat(ws): handle non-JSON messages as raw HTML with cancelable event#3641
1cg merged 2 commits intobigskysoftware:fourfrom
stukennedy:ws-raw-message-handling

Conversation

@stukennedy
Copy link

Summary

When the WebSocket extension receives a non-JSON message (plain text/HTML), it now handles it gracefully instead of silently dropping it.

Behavior

  1. Raw HTML → hx-target: If the connection element has hx-target, raw HTML messages are swapped into that target using htmx.swap()
  2. No hx-targetswap:none: Without an explicit target, raw messages use swap:none to avoid accidentally overwriting the connection element's contents
  3. <hx-partial> still works: If the raw message contains <hx-partial> elements, they're extracted and processed normally (reaching their own targets) — even without hx-target on the connection element
  4. Cancelable event: A htmx:ws:rawMessage event fires before any swap, with event.detail.data containing the raw string. Call preventDefault() to cancel the default swap behavior

Why

This came up in discussion on #3638 — after switching to htmx.swap(), raw HTML messages could inadvertently wipe the connection element's contents if no hx-target was set. This PR makes raw message handling explicit and safe.

Tests

5 new tests covering all scenarios:

  • Raw HTML swaps into hx-target
  • swap:none when no hx-target (protects connection element)
  • <hx-partial> in raw messages still reaches targets without hx-target
  • htmx:ws:rawMessage event fires with data
  • preventDefault() cancels the default swap

All 59 WS extension tests passing.

Stu Kennedy added 2 commits January 29, 2026 20:31
Non-JSON WebSocket messages now swap as raw HTML instead of being
dropped. Fires a cancelable htmx:ws:rawMessage event before swapping,
allowing custom handling when needed.

- If hx-target is set: swaps into target using element's swap style
- If no hx-target: uses swap:none to protect connection element,
  but hx-partial tags in payload still reach their own targets
- preventDefault() on the event skips default swap for custom handling

Replaces the old htmx:wsUnknownMessage event which only notified
but took no action on non-JSON data.
Tests cover:
- Non-JSON messages swap as raw HTML into hx-target
- swap:none used when no hx-target (protects connection element)
- hx-partial tags in raw messages still reach their targets
- htmx:ws:rawMessage event fires with message data
- preventDefault() on rawMessage cancels default swap
@1cg 1cg merged commit 3a72a1d into bigskysoftware:four Jan 29, 2026
@stukennedy stukennedy deleted the ws-raw-message-handling branch January 29, 2026 20:58
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