Headers HTMX — HTMX

HTMX menggunakan HTTP headers untuk komunikasi antara client dan server. Request Headers (dikirim HTMX) HX-Request: true — menandai ini request HTMX…

Selain alamat dan isi, setiap request dan balasan HTTP membawa header: baris-baris Nama: nilai yang menerangkan pesan itu. htmx menempelkan beberapa header sendiri di setiap request, dan server bisa membalas dengan header yang memberi perintah ke htmx. Bayangin nota titipan di Laundry Bu Rini. Kasir menulis di pojok nota "dari meja depan, untuk papan nomor 12" (header request). Bu Rini mengembalikan nota dengan kertas tempel "taruh di rak lain" atau "ganti papannya" (header balasan).

🧪 Tebakan cepat: Tombol <button id="cek-12" hx-get="/order/12/status" hx-target="#status-12"> diklik. Header HX-Target yang dikirim htmx berisi #status-12 atau status-12? Jawabannya ada di bagian "Header yang dikirim htmx".

Header yang dikirim htmx

Klik Cek status di baris #12 mengirim request ini:

GET /order/12/status HTTP/1.1
HX-Request: true
HX-Trigger: cek-12
HX-Target: status-12
HX-Current-URL: http://localhost:8000/papan
Header Isinya Kapan ada
HX-Request true setiap request htmx
HX-Trigger id elemen pemicu, cek-12 kalau pemicunya punya id
HX-Trigger-Name name elemen pemicu, misalnya cari kalau pemicunya punya name
HX-Target id target, status-12 kalau target-nya punya id
HX-Current-URL alamat halaman sekarang setiap request htmx
HX-Boosted true link atau form yang di-boost

HX-Target berisi id saja, tanpa #: status-12. Itu jawaban tebakannya. Saat form dikirim, HX-Trigger berisi id form-nya (terima), bukan tombolnya, karena yang memicu submit adalah form.

hx-headers: header tambahan

<button hx-get="/api/data" hx-headers='{"X-Custom": "my-value"}' hx-target="#result">
  Load with Headers
</button>

Satu route, dua bentuk balasan

Server bisa membaca HX-Request untuk memilih balasan: potongan HTML untuk htmx, halaman utuh untuk browser biasa.

Route::get('/papan', function (Request $request) {
    $orders = Order::where('nama', 'like', '%'.$request->query('cari').'%')->get();
    $view = $request->header('HX-Request') ? 'papan._daftar' : 'papan.index';

    return response()->view($view, ['orders' => $orders])
        ->header('Vary', 'HX-Request');
});

Vary: HX-Request untuk cache

Browser (dan CDN) menyimpan balasan di cache dengan kunci alamatnya. Tanpa Vary, /papan?cari=darto versi potongan <li> dan versi halaman utuh berebut satu tempat. Kasir mencari "darto", membuka Laporan lewat link biasa, lalu menekan Back: browser mengambil /papan?cari=darto dari cache dan mendapat potongan <li> dari request htmx tadi. Yang tampil daftar polos tanpa layout, tanpa kolom cari.

Vary: HX-Request membuat cache menyimpan dua versi, satu per nilai HX-Request. Back tanpa HX-Request mendapat halaman utuh. Satu hal lagi: saat riwayat htmx gak ada di cache-nya sendiri, htmx 2.0.11 meminta halaman utuh dengan HX-Request: true. Pasang <meta name="htmx-config" content='{"historyRestoreAsHxRequest": false}'> supaya request itu gak dikira request potongan.

Header balasan: server memberi perintah

Header balasan Yang dilakukan htmx Contoh di papan
HX-Trigger memicu event di client (pelajaran events) orderBaru sesudah order dicatat
HX-Redirect pindah halaman penuh ke alamat itu Tutup kasir, lalu ke /laporan
HX-Refresh true: muat ulang seluruh halaman harga naik dari Rp 7.000 jadi Rp 8.000 per kg
HX-Retarget ganti target dengan selector ini order dobel: tukar baris #order-14 yang sudah ada
HX-Reswap ganti cara swap outerHTML untuk baris itu
HX-Push-Url taruh alamat ini di address bar dan riwayat /papan?cari=darto sesudah mencari
// Order dobel: perbarui baris yang sudah ada, bukan menambah baris baru
return response()->view('papan._baris', ['order' => $order])
    ->header('HX-Retarget', '#order-14')
    ->header('HX-Reswap', 'outerHTML');

// Tutup kasir: pindah ke halaman laporan
return response('', 200)->header('HX-Redirect', '/laporan');

⚠️ Jebakan yang sering ketemu

TL;DR: htmx mengirim HX-Request: true di setiap request, plus HX-Trigger (id pemicu), HX-Trigger-Name (name pemicu), HX-Target (id target, tanpa #), HX-Current-URL, dan HX-Boosted untuk yang di-boost. hx-headers='{"X-Custom": "my-value"}' menambah header sendiri (JSON, kutip satu di luar), dan diwariskan, misalnya token CSRF di <body>. Server membaca HX-Request untuk membalas potongan atau halaman utuh, dan wajib menambah Vary: HX-Request supaya cache gak tertukar. Header balasan memberi perintah: HX-Trigger (event), HX-Redirect (pindah halaman penuh), HX-Refresh (muat ulang), HX-Retarget dan HX-Reswap (ganti target dan cara swap), HX-Push-Url (address bar). Untuk request htmx, pakai HX-Redirect, bukan redirect 302.

Yang akan kamu pelajari