hx-swap="none" prevents HX-Retarget
Hi! I think I found some unexpected behavior around setting hx-swap="none" in a form.
It's easy to bypass but want to understand what's happening or perhaps offer an update to the docs.
Code
The following code fails to swap in the alert when an error occurs:
<!-- part of index.html -->
<div id="flash-message"></div>
<main>
<form
hx-post="/submit"
hx-swap="none"
>
...
<button type="submit">Submit</button>
</form>
</main>
func (h *Handler) Submit(c *gin.Context) {
...
# error handling
if err != nil {
c.Header("HX-Retarget", "#flash-message")
c.Header("HX-Swap", "innerHTML")
component := views.FlashError(err)
component.Render(c.Request.Context(), c.Writer)
return
}
...
# happy path
c.Header("HX-Redirect", "/yay")
c.String(http.StatusOK, "Success")
}
Behavior
When there is no error, the redirect occurs as expected. When there is an error, the request goes through "successfully". When checking the response in the network tab, I see that the headers are set to the expected values:
- HX-Retarget = "#flash-message"
- HX-Swap = "innerHTML"
But the flash error message HTML from the response is not swapped in.
Expected Behavior
I thought the #flash-message content would get swapped in.
NOTE: removing the hx-swap="none" allows this to work.
Suggestion
I see that an Out of Band swap would work but maybe with hx-swap="none" it prevents any in-band responses, even if it's a retargeting that occurs through header changes? If this is the expected behavior, I would update the docs to include that setting hx-swap="none" will prevent the use of a swap via HX-Retarget.
But I can also see this being a bug because I would expect a header change using HX-Retarget to override the "normal" (in-band) paths.
Context
Docs say:
does not append content from response (Out of Band Swaps and Response Headers will still be processed)
HTMX Version: 2.0.6
an oob swap will work fine regardless of the retarget or swap stratagy. It is very common pattern to set hx-swap to none when your response is going to only include hx-swap-oob responses as this prevents the target being blanked out after all the response data is consumed as oob swaps and it finally uses "" to swap into target.
There is no hx-swap response header in htmx it is hx-reswap to do what you want https://htmx.org/reference/#response_headers