The hx-swap attribute controls where the response content goes.
Defaults to innerHTML (configurable via htmx.config.defaultSwap)
Examples
<!-- Replace content in container --> <div hx-get="..." hx-swap="innerHTML"></div> <!-- Append to list and scroll down --> <div hx-get="..." hx-swap="beforeend scroll:bottom"></div> <!-- Update form with smooth transition --> <form hx-post="..." hx-swap="outerHTML transition:true"></form>
Swap Methods
innerHTML
Replaces content inside element.
<div hx-get="..." hx-swap="innerHTML"> ... <!-- This gets replaced --> </div>
outerHTML
Replaces entire element.
<!-- This... --> <div hx-get="..." hx-swap="outerHTML"> ... </div> <!-- ...gets replaced -->
textContent
Replaces the text content of the element, without parsing the response as HTML.
Useful when the response is plain text and you want to avoid any HTML injection.
<span hx-get="..." hx-swap="textContent">0</span>
beforebegin / before
Inserts content before element.
<!-- Response goes here --> <div hx-get="..." hx-swap="beforebegin"> ... </div>
Can also use hx-swap="before"
afterbegin / prepend
Inserts content as first child.
<div hx-get="..." hx-swap="afterbegin"> <!-- Response goes here --> ... </div>
Can also use hx-swap="prepend"
beforeend / append
Inserts content as last child.
<div hx-get="..." hx-swap="beforeend"> ... <!-- Response goes here --> </div>
Can also use hx-swap="append"
afterend / after
Inserts content after element.
<div hx-get="..." hx-swap="afterend"> ... </div> <!-- Response goes here -->
Can also use hx-swap="after"
innerMorph
Morphs content inside element, preserving state and focus.
Uses the idiomorph algorithm.
<div hx-get="..." hx-swap="innerMorph"> ... <!-- This gets morphed --> </div>
outerMorph
Morphs entire element, preserving state and focus.
Uses the idiomorph algorithm.
<!-- This... --> <div hx-get="..." hx-swap="outerMorph"> ... </div> <!-- ...gets morphed -->
Morph exclusions:
Add attributes to your server templates to exclude elements from morphing:
hx-morph-skip— freeze entire element (attrs + children unchanged)hx-morph-skip-children— freeze children only, attrs still update
Or configure globally via htmx.config.morphSkip and htmx.config.morphSkipChildren.
outerSync
Syncs attributes from the response’s outer element onto the target, then replaces the target’s children. The target element itself stays in the DOM — listeners and component state are preserved.
Useful when the server returns a full element (e.g. <section class="active">...</section>) and you want the target’s attributes updated without replacing the element itself.
<!-- Target keeps its listeners, gets new attrs + children --> <section id="main" hx-get="..." hx-swap="outerSync"> ... </section>
outerHTML on document.body automatically upgrades to outerSync so that body attributes (classes, data-attrs) are preserved across full-page swaps.
delete
Removes element (ignores response content).
<!-- This... --> <div hx-delete="..." hx-swap="delete"> ... </div> <!-- ...is removed -->
none
Doesn’t insert content (out-of-band swaps still work).
<div hx-get="..." hx-swap="none"> <!-- Response not inserted, but OOB swaps happen --> </div>
upsert
Updates existing elements by ID and inserts new ones.
Requires the upsert extension.
<div hx-get="..." hx-swap="upsert"> <!-- Existing elements with matching IDs are updated, new ones are inserted --> </div>
Modifiers
Customize swap behavior with modifiers.
transition
Enables View Transitions API for smooth page transitions.
<div hx-swap="innerHTML transition:true"></div>
Enable globally: htmx.config.transitions = true
swap
Adds delay before swap.
Useful for showing loading states or coordinating with CSS animations.
<div hx-swap="innerHTML swap:1s"></div>
Default: 0ms
settle
Adds delay between the swap and the settle phase.
Useful for synchronizing htmx with CSS transition timing.
<div hx-swap="innerHTML settle:200ms"></div>
Default: 1ms
ignoreTitle
Prevents updating the page <title>.
By default, htmx updates the page title from <title> tags in responses.
<div hx-swap="innerHTML ignoreTitle:true"></div>
scroll
Auto-scroll to swapped content.
Useful for infinite scroll, chat messages, or focusing attention on new content.
<div hx-swap="beforeend scroll:bottom"></div>
Values: top, bottom
Target a different element:
<div hx-swap="innerHTML scroll:top scrollTarget:#other"></div>
Scroll the window:
<div hx-swap="innerHTML scroll:window:top"></div>
show
Scrolls to show the target element in viewport.
Values: top, bottom, none
<div hx-swap="innerHTML show:top"></div>
Show a different element:
<div hx-swap="innerHTML show:top showTarget:#other"></div>
Boosted forms default to show:top. Disable:
<form hx-swap="show:none"></form>
target
Override swap target inline. Alternative to using hx-target attribute.
<div hx-swap="innerHTML target:#results"></div>
strip
Controls whether the outer element of the response content is removed before swapping.
<div hx-swap="innerHTML strip:true"></div>
swapEmpty
Controls whether an empty response body still performs the main swap (which clears the target). swapEmpty:false skips the main swap; swapEmpty:true (or a bare swapEmpty) forces it.
<!-- Skip the main swap when the response is empty --> <div hx-swap="innerHTML swapEmpty:false"></div> <!-- Force the main swap even when the response is empty --> <div hx-swap="innerHTML swapEmpty:true"></div>
Defaults to htmx.config.defaultSwapEmpty.
Caveats
outerHTMLondocument.bodyautomatically upgrades toouterSyncto preserve body attributes (classes, data-attrs). UseouterSyncexplicitly if you want this behaviour on other elements.