#htmx
#html
#frontend
Day 10: Server-Side Validation
Welcome to Day 10.
In a SPA, you validate JSON responses. In htmx, you return HTML with errors.
The Pattern
- User submits form.
- Server checks data.
- If invalid -> Return the Form HTML again, but with error messages and values filled in.
- If valid -> Return success message or redirect.
Inline Validation (UX)
You want real-time feedback? Trigger on change or blur.
<input
name="email"
hx-post="/validate/email"
hx-trigger="blur"
hx-target="#email-error"
/>
<span id="email-error"></span>
Server Response (if invalid):
<span style="color:red">Email already taken</span>
Server Response (if valid):
<span>✅</span>
Handling HTTP Statuses
By default, htmx ignores 4xx and 5xx error responses (it doesn’t swap). But for validation (422 Unprocessable Entity), we want to swap (to show the error form).
<!-- Enable swapping on error ranges -->
<body hx-ext="response-targets">
...
</body>
Or, simpler: Just return 200 OK containing the form errors. This is often the pragmatic htmx way.
Challenge for Day 10
- Create a “Sign Up” form.
- Username, Email.
- If Username is “admin”, the server should return the form again with an error “Reserved name”.
- Use
hx-target="this"(replace the whole form).
Solution:
<!-- form.html template -->
<form hx-post="/signup" hx-swap="outerHTML">
<label>Username</label>
<input name="username" value="admin" class="error">
<div class="error-msg">Reserved name</div>
<button>Submit</button>
</form>
The server literally re-renders the template with the error state included.
Tomorrow: Infinite Scroll.