htmx
htmx copied to clipboard
unexpected behaviour with head-support - bug?
In the head-support docs it says
With this installed, all responses that htmx receives that contain a head tag in them (even if they are not complete HTML documents with a root element) will be processed.
Maybe I have a wrong understanding of the concept of the head-support extension. Is it designed for handling responses which exclusively contain markup for head or can we combine markup to be swapped in the body and head markup in the same response?
My hx-get response contains both, a div that is swapped (outerHTML) with the corresponding div in the body and a head element with meta tags, title, links etc that should be used to swap out the whole head.
Truncated example response:
<div class="container">
content
</div>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
...
</head>
Current Behaviour
Swapping of the head works fine.
But when the div in the response is swapped into the body, all child elements of head are appended to the target, too. head tags themselves are stripped out.
So the target look something like:
<div class="container">
content
</div>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
...
Expected Behaviour
I would expect that if a response contained markup to be swapped in the body AND a head element, the head element would be completely removed from the response before the markup is swapped. And then the head element would be swapped out. Looking at the extraction logic at https://github.com/bigskysoftware/htmx/blob/4bc7c9710e99369a8c659f9b865e75866fd7a446/src/ext/head-support.js#L20, it seems the head markup is not being removed from the content.
I think the cause of this behaviour is the mergeHead function being called in the htmx:afterSwap event. It should be called beforeSwap, extract and remove head markup, do the head merge logic and pass on the cleaned markup for swapping.