hx-get & hx-post: Declarative AJAX & HX-Request Headers
- Last updated
- Prerequisites:
- HTML Form basics
- HTTP GET/POST methods
- htmx
- ajax
- hx-get
- hx-post
- headers
- hypermedia
Read at your depth
The practical view
`hx-get` and `hx-post` trigger AJAX requests directly from HTML attributes: `<button hx-get="/api/users" hx-target="#list">Load</button>`. HTMX intercepts the click, sends an AJAX request with custom headers (like `HX-Request: true`), and swaps the returned HTML string into `#list` (`innerHTML` by default).
The same idea in other frameworks
`fetch('/api/users').then(r => r.json()).then(data => setUsers(data))`.`this.http.get<User[]>('/api/users').subscribe(data => this.users = data)`.`const users = ref([]); onMounted(async () => users.value = await $fetch('/api/users'))`.`<button hx-get="/api/users" hx-target="#list">Load Users</button>`.Legacy vs modern
Client-Side Fetch & DOM Construction vs Declarative hx-get
Manual JavaScript fetch requires parsing JSON and appending elements; HTMX requests and swaps HTML partials in one attribute.
fetch(url).then(r => r.text()).then(html => el.innerHTML = html); // ❌ Imperative plumbing<button hx-get="/api/content" hx-target="#content">Load</button> // ✅ NEW: Zero custom JSInterview gotchas
Context
Interviewers test your knowledge of HTMX request header inspection for backend conditional rendering.
The mechanical answer
HTMX automatically sends the **`HX-Request: true`** HTTP header on every AJAX request. Server-side controllers inspect this header: if present, the server renders and returns only the minimal HTML partial (e.g. `<tr>...</tr>`); if absent (e.g. initial direct browser page load), the server renders the full page template including `<head>`, `<body>`, and navigation bars.
Trap
Failing to check `HX-Request` on endpoints serving both direct visits and HTMX partials will cause the entire HTML page layout to be nested inside the target element.
Context
Checks understanding of natural event triggers in HTMX.
The mechanical answer
HTMX assigns default triggers based on element semantics: `<input>`, `<textarea>`, and `<select>` trigger on the `change` event; `<form>` triggers on the `submit` event; all other elements (like `<button>`, `<div>`, `<a>`) trigger on the `click` event.
Trap
You can override any default trigger using `hx-trigger="mouseenter"` or `hx-trigger="keyup changed delay:500ms"`.