Search for a command to run...
Last updated June 9, 2026
Ctrovalidate and HTMX share a "markup-first" philosophy. By combining them, you can build powerful, validated AJAX forms with almost zero custom JavaScript.
Load ctrovalidate-browser via CDN or NPM and initialize it on your HTMX-powered form.
<form
hx-post="/update-profile"
hx-target="#response"
id="profile-form"
>
<input name="username" data-ctrovalidate-rules="required|minLength:4" />
<div class="error-msg"></div>
<button type="submit">Update</button>
</form>
<script type="module">
import { Ctrovalidate } from 'https://cdn.jsdelivr.net/npm/ctrovalidate-browser@1.0.0/dist/index.js';
const validator = new Ctrovalidate(document.getElementById('profile-form'));
// Intercept HTMX request to validate first
document.body.addEventListener('htmx:beforeRequest', async (evt) => {
if (evt.detail.target.id === 'profile-form') {
const isValid = await validator.validate();
if (!isValid) evt.preventDefault(); // Stop the AJAX request
}
});
</script>HTMX often swaps new content into the DOM. When these fragments contain new validation rules, use validator.refresh().
document.body.addEventListener('htmx:afterOnLoad', () => {
// Re-scan for new data-ctrovalidate-rules in the swapped content
validator.refresh();
});If your server returns an error fragment (e.g., 422 Unprocessable Entity), Ctrovalidate's browser controller will automatically detect and manage the new error containers if they follow the errorMessageClass pattern.
hx-validate="true": While HTMX has basic internal validation support, using Ctrovalidate via htmx:beforeRequest gives you more granular control and accessibility.htmx:beforeRequest listener that checks for a specific attribute (e.g., data-validate) on the form.htmx-request class with Ctrovalidate's pendingClass for consistent loading indicators.