Extensions HTMX — HTMX

HTMX Extensions menambahkan fitur tambahan melalui plugin system. Menggunakan Extension Extensions Populer json-enc — Encode request body sebagai JSON…

Extension adalah tambahan yang memberi htmx kemampuan baru tanpa mengubah intinya: mengirim form sebagai JSON, menaruh balasan error di kotak lain, memuat halaman sebelum diklik. Di htmx 2, setiap extension adalah paket sendiri bernama htmx-ext-.... Ia dipasang dua langkah: dimuat dengan tag <script> sesudah htmx, lalu dinyalakan dengan hx-ext di elemen yang memakainya. Bayangin aksesori mesin cuci di Laundry Bu Rini. Pengering tambahan harus dibeli dan dipasang dulu (script), lalu dinyalakan di mesin yang mau memakainya (hx-ext). Menekan tombol pengering di mesin yang belum dipasangi gak menghasilkan apa-apa.

🧪 Tebakan cepat: Form Terima cucian punya hx-ext="json-enc", tapi tag script extension-nya lupa dipasang. Kasir menekan Terima. Body-nya JSON, form-encoded, atau muncul error? Jawabannya ada di bagian "Memasang extension: muat, lalu nyalakan".

Memasang extension: muat, lalu nyalakan

<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/[email protected]"></script>

<body hx-ext="response-targets">
  <form hx-post="/order" hx-ext="json-enc">...</form>
</body>

json-enc: kirim form sebagai JSON

<form id="terima" hx-post="/order" hx-ext="json-enc" hx-target="#papan-order" hx-swap="beforeend">
  <input name="nama" value="Bu Tini">
  <input name="berat" value="4">
  <label><input type="checkbox" name="layanan" value="setrika" checked> Setrika</label>
  <label><input type="checkbox" name="layanan" value="lipat" checked> Lipat</label>
  <button>Terima cucian</button>
</form>
Tanpa json-enc Dengan json-enc
Content-Type application/x-www-form-urlencoded application/json
Body nama=Bu%20Tini&berat=4&layanan=setrika&layanan=lipat {"nama":"Bu Tini","berat":"4","layanan":["setrika","lipat"]}

response-targets: balasan error ke kotak lain

Dari pelajaran validasi: htmx 2 gak menukar balasan 4xx dan 5xx. response-targets memberi tujuan sendiri per status:

<body hx-ext="response-targets">
  <div id="galat"></div>
  <form id="terima" hx-post="/order" hx-target="#papan-order" hx-swap="beforeend"
        hx-target-422="#galat">
    ...
  </form>
  <ul id="papan-order">...</ul>
</body>
Balasan server Mendarat di
201, <li id="order-15">...</li> #papan-order, seperti biasa
422, <p>Kapasitas hari ini tinggal 20 kg.</p> #galat
500 tanpa aturan gak ditukar

preload: mulai memuat sebelum diklik

<body hx-ext="preload">
  <button hx-get="/laporan" hx-target="#laporan" preload="mouseover">Laporan hari ini</button>

loading-states: indikator lewat data-loading

<style>[data-loading] { display: none; }</style>
<body hx-ext="loading-states">
  <form id="terima" hx-post="/order" data-loading-states>
    <button data-loading-disable>Terima cucian</button>
    <span data-loading>Menyimpan...</span>
  </form>

Satu lagi, cukup diketahui: head-support menggabungkan isi <head> (title, meta, CSS) dari balasan halaman yang di-boost. Pakai kalau halaman-halamanmu butuh CSS atau meta yang berbeda.

⚠️ Jebakan yang sering ketemu

TL;DR: Di htmx 2, extension adalah paket htmx-ext-... sendiri: muat script-nya sesudah htmx, lalu nyalakan dengan hx-ext (diwariskan, dipisah koma, ignore: untuk mematikan). Tanpa script-nya, hx-ext diabaikan diam-diam. json-enc mengirim body sebagai application/json ({"nama":"Bu Tini","berat":"4"}). response-targets menaruh balasan per status di target lain (hx-target-422="#galat", hx-target-error), dengan hx-ext di elemen yang juga memuat target-nya. preload memuat GET lebih dulu saat tombol mouse ditekan atau kursor diam 100 ms, dan butuh cache yang diizinkan server. loading-states memakai data-loading, data-loading-disable, dan data-loading-delay, dibatasi dengan data-loading-states. head-support menggabungkan <head> dari halaman yang di-boost.

Yang akan kamu pelajari