hx-vals & hx-include: Dynamic JSON and Form Payload Serialization
- Last updated
- Prerequisites:
- HTML Form serialization
- JSON syntax in HTML attributes
- htmx
- hx-vals
- hx-include
- serialization
- forms
- payload
Read at your depth
The practical view
`hx-vals` adds extra parameters to an HTMX request: `hx-vals='{"role": "admin", "source": "banner"}'`. For dynamic JavaScript expressions, use `js:` prefix: `hx-vals='js:{timestamp: Date.now()}'`. `hx-include="#other-form, #search-input"` includes the values of external inputs or forms in the current request payload.
The same idea in other frameworks
`const payload = { ...formData, role: 'admin', timestamp: Date.now() }`.`this.http.post(url, { ...this.form.value, role: 'admin' })`.`await $fetch(url, { body: { ...form, role: 'admin' } })`.`hx-vals='js:{timestamp: Date.now()}' hx-include="#sidebar-filters"`.Legacy vs modern
Manual JS Payload Assembly vs Declarative hx-include
Assembling payloads from disconnected inputs in JS requires querySelectors; `hx-include` serializes them declaratively.
body: JSON.stringify({ a: inputA.value, b: inputB.value }); // ❌ Manual collection<button hx-post="/checkout" hx-include="#filters, #coupon" hx-vals='js:{clientTime: Date.now()}'> // ✅ NEWInterview gotchas
Context
Interviewers test your knowledge of HTTP protocol structure within HTMX.
The mechanical answer
`hx-vals` adds parameters to the **request body** (for POST/PUT) or query string parameters (for GET). `hx-headers` adds custom **HTTP headers** to the request (e.g. `hx-headers='{"Authorization": "Bearer token"}'` or `{"X-Custom-ID": "123"}`).
Trap
Do not pass authentication tokens into `hx-vals` if your backend middleware expects them in the `Authorization` HTTP header.
Context
Checks attention to valid HTML attribute parsing syntax.
The mechanical answer
HTML attributes use double or single quotes. Since standard JSON keys and string values *strictly require* double quotes (`{"key": "value"}`), the HTML attribute itself must be wrapped in single quotes: `hx-vals='{"key": "value"}'`. Wrapping in double quotes without escaping will create invalid HTML and cause JSON parsing errors.
Trap
`hx-vals="{'key': 'value'}"` is invalid JSON and will fail to parse.