Targets and swaps
Choose a target
Point the response at a stable page region with a CSS selector or a relative target.
Most HTMX interactions update a region of the page, not the control that triggered them. hx-target points the response at that region.
A search input can update a results container:
<input name="q" hx-get="/search" hx-target="#results">
<div id="results"></div>
hx-target accepts a CSS selector and is inherited, so a stable container can define the target for several controls inside it. A filter form on #task-panel can set hx-target="#task-list" once on the wrapper instead of repeating it on every button.
Choose the smallest region that contains the complete changed state. If a search changes the result rows, count, and empty message, target a wrapper containing all three, not only the <ul>. Returning fresh rows beside a stale “12 results” label is a target boundary bug, not a server bug.
A target that is too broad replaces unrelated state. It may reset focus, scroll position, media playback, or client widgets living inside that region. A target that is too narrow leaves stale totals and actions beside fresh results.
Give major target regions stable IDs because they are easy to inspect, address from response headers, and preserve across full-page and fragment templates. Do not reuse the same ID elsewhere in the document. Duplicate IDs make document.querySelector and HTMX targeting pick the wrong node unpredictably.
Exercise both response shapes: return three results, then return none. If every piece of search state becomes correct from one fragment, the boundary is coherent. If client code must clean up neighboring elements afterward, widen the target or use one deliberate out-of-band update.
Try this on your own project: draw a box around everything that must change together for one interaction. That box is your target.
Lesson completed