Svelte Integration
Ctrovalidate integrates seamlessly with Svelte using the bind:this directive and onMount lifecycle function.
Installation
bash
npm install ctrovalidateBasic Pattern
Use Svelte's bind:this to get a reference to the form element, then initialize Ctrovalidate in onMount.
Complete Example
svelte
<script lang="ts">
import { onMount } from 'svelte';
import { Ctrovalidate, LogLevel } from 'ctrovalidate';
let formElement: HTMLFormElement;
let validator: Ctrovalidate | null = null;
onMount(() => {
if (formElement) {
validator = new Ctrovalidate(formElement, {
realTime: true,
logLevel: LogLevel.WARN
});
}
});
async function handleSubmit() {
if (validator && await validator.validate()) {
const formData = new FormData(formElement);
console.log('Form valid:', Object.fromEntries(formData));
// Submit to API
}
}
</script>
<form bind:this={formElement} on:submit|preventDefault={handleSubmit} novalidate>
<div>
<label for="username">Username</label>
<input
type="text"
id="username"
name="username"
data-ctrovalidate-rules="required|minLength:3"
/>
<div class="error-message"></div>
</div>
<div>
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
data-ctrovalidate-rules="required|email"
/>
<div class="error-message"></div>
</div>
<button type="submit">Sign Up</button>
</form>Dynamic Fields
When using {#if} or {#each} to add/remove fields, call refresh() after the DOM updates.
Example: Conditional Fields
svelte
<script lang="ts">
import { onMount, afterUpdate } from 'svelte';
import { Ctrovalidate } from 'ctrovalidate';
let formElement: HTMLFormElement;
let validator: Ctrovalidate | null = null;
let showPhone = false;
onMount(() => {
if (formElement) {
validator = new Ctrovalidate(formElement, {
realTime: true
});
}
});
// Refresh validator when fields change
afterUpdate(() => {
validator?.refresh();
});
</script>
<form bind:this={formElement} novalidate>
<div>
<label>
<input type="checkbox" bind:checked={showPhone} />
Add phone number
</label>
</div>
{#if showPhone}
<div>
<label for="phone">Phone</label>
<input
id="phone"
name="phone"
data-ctrovalidate-rules="required|phone"
/>
<div class="error-message"></div>
</div>
{/if}
<button type="submit">Submit</button>
</form>TypeScript Support
Full TypeScript support with proper types:
typescript
import { Ctrovalidate, LogLevel, type CtrovalidateOptions } from 'ctrovalidate';
const options: CtrovalidateOptions = {
realTime: true,
logLevel: LogLevel.DEBUG,
errorClass: 'border-red-500',
errorMessageClass: 'text-red-600 text-sm mt-1'
};Best Practices
1. Initialize in onMount
Always initialize the validator after the component mounts:
typescript
onMount(() => {
if (formElement) {
validator = new Ctrovalidate(formElement);
}
});2. Use afterUpdate for Dynamic Fields
Refresh the validator after DOM changes:
typescript
afterUpdate(() => {
validator?.refresh();
});3. Use novalidate
Disable browser validation:
svelte
<form bind:this={formElement} novalidate>4. Clean Up (Optional)
Svelte automatically cleans up when components are destroyed, but you can manually destroy the validator if needed:
typescript
import { onDestroy } from 'svelte';
onDestroy(() => {
validator?.destroy();
});Benefits
- No Reactivity Overhead: Validation runs in the DOM, not Svelte's reactive system
- TypeScript Support: Full type definitions included
- Accessibility: Automatic ARIA attribute management
- Scoped Styles: Works with
<style>blocks
Next Steps
- Dynamic Fields Guide — Managing field lifecycle
- API Reference — All 9 instance methods
- Custom Rules — Creating validation logic
- Configuration — Customizing options