Hyper · htmx-style

Targets & swaps

kj-target says where; kj-swap says how. Watch all eight strategies land around the same element.

kj-target takes any CSS selector (default: the element itself). kj-swap picks the insertion strategy:

kj-swapEffectTypical use
innerHTMLReplace the target's content (default)Panels, results
outerHTMLReplace the target itselfEdit-in-place rows, delete (empty response)
beforeendAppend insideFeeds, chat, "load more"
afterbeginPrepend insideNewest-first lists
beforebegin / afterendInsert as a siblingInline forms, notices
textContentInsert as plain textCounters, untrusted text
noneMake the request, change nothingFire-and-forget, analytics

Live · Swap-strategy visualizer

■ target — watch where each response lands
View the source for this demo
HTML
<div class="row">
  <button type="button" kj-get="/api/swaps/innerHTML.html" kj-target="#swap-anchor" kj-swap="innerHTML">innerHTML</button>
  <button type="button" kj-get="/api/swaps/beforebegin.html" kj-target="#swap-anchor" kj-swap="beforebegin">beforebegin</button>
  <button type="button" kj-get="/api/swaps/afterbegin.html" kj-target="#swap-anchor" kj-swap="afterbegin">afterbegin</button>
  <button type="button" kj-get="/api/swaps/beforeend.html" kj-target="#swap-anchor" kj-swap="beforeend">beforeend</button>
  <button type="button" kj-get="/api/swaps/afterend.html" kj-target="#swap-anchor" kj-swap="afterend">afterend</button>
  <button type="button" kj-get="/api/swaps/innerHTML.html" kj-target="#swap-anchor" kj-swap="textContent">textContent</button>
  <button type="button" kj-get="/api/swaps/outerHTML.html" kj-target="#swap-anchor" kj-swap="outerHTML">outerHTML</button>
  <button type="button" id="swap-reset">Reset</button>
</div>
<div id="swap-zone" aria-live="polite" style="margin-top:14px">
  <div class="sb" id="swap-anchor">■ target — watch where each response lands</div>
</div>
JavaScript
$('#swap-reset').on('click', () =>
  $('#swap-zone').html('<div class="sb" id="swap-anchor">■ target — watch where each response lands</div>'));

More examples

Patterns

HTML
<!-- Chat: append each new message -->
<form kj-post="/chat/send" kj-target="#messages" kj-swap="beforeend">…</form>

<!-- Delete a row: server returns an empty body, the row disappears -->
<button kj-delete="/rows/9" kj-target="#row-9" kj-swap="outerHTML">Delete</button>

<!-- Track a click without touching the page -->
<a href="/pricing" kj-post="/track?e=pricing" kj-swap="none">Pricing</a>

API

kj-target="#selector"

Where the response HTML goes (default: the element itself).

Reference: kj-target →
kj-swap="innerHTML | outerHTML | textContent | beforebegin | afterbegin | beforeend | afterend | none"

How the response is inserted into the target. outerHTML replaces the target entirely; the four position values insert adjacent to it; none makes the request without touching the DOM.

Reference: kj-swap →

Migrating

Coming from htmxSame swap names. htmx swap modifiers (swap:1s, settle, scroll:top, show), hx-select and out-of-band swaps (hx-swap-oob) are not included.

Related features