createValidation Overview
Relevant source files
The following files were used as context for generating this wiki page:The createValidation function is a helper utility within the @opensky/remotes package designed to enhance the user experience of form validation when working with SvelteKit's remote form functions. It provides reactive state management for validation issues, implementing a specific logic: validation issues for a field are shown when the user leaves the field (onblur), but are cleared as soon as the user starts typing in it again (oninput). This prevents validation errors from appearing distractingly during input.
This utility is often used in conjunction with its sibling helper, createEnhancedForm, which provides a more structured way to handle form submission lifecycles. The createValidation helper manages client-side issue display, debounced server validation, and manual issue management.
Sources: packages/remotes/README.md:3-11, packages/remotes/src/lib/validation.svelte.ts:10-14
Core Concepts
The primary goal of createValidation is to provide a better UX for form validation. It achieves this through a combination of event handling, state management, and debounced communication with the server.
- Reactive State: It uses Svelte 5 runes (
$state) to create a reactiveissuesobject that stores validation messages for form fields. - Event-Driven Validation: It provides
onblurandoninputevent handlers. Theonblurevent triggers validation, while theoninputevent clears existing issues for that field as the user corrects them. - Debounced Remote Validation: To avoid excessive server requests on every keystroke or blur event, it uses a debounced function (
useDebouncefrom therunedlibrary) to call the remote form'svalidate()method. - Nested Field Support: Field paths can be specified using dot notation (e.g.,
'address.state'), and the helper will correctly manage issues in a nested object structure.
Sources: packages/remotes/README.md:6-8, packages/remotes/src/lib/validation.svelte.ts:15-16, 80-86
Initialization and API
The createValidation function is exported from the main package entry point. It is initialized by passing a SvelteKit RemoteForm instance to it.
Sources: packages/remotes/src/lib/index.ts:1, packages/remotes/src/lib/validation.svelte.ts:14
import { createValidation } from '@opensky/remotes';
import { myForm } from './myForm.remote';
const valid = createValidation(myForm);
Sources: packages/remotes/README.md:14-16
The function returns an object containing several methods and properties to manage and display validation state.
The following diagram shows the components involved in the createValidation system.
Returned Methods
The object returned by createValidation provides the following API:
| Method | Description |
|---|---|
fields(path) | Returns onblur and oninput event handlers for a given field path. Registers the path for validation tracking. |
issues(path) | Returns an array of validation issue strings for a field path, or null if there are no issues. |
allIssues() | Returns the entire reactive object containing all validation issues for all registered fields. |
addIssue(path, issue) | Manually adds a custom validation error message to a specific field. Useful for client-side-only validation logic. |
reset() | Clears all validation issues from the state. |
validateAll() | Triggers validation for all registered fields against the server. This is typically used on form submission. |
updateIssues() | Populates the local issue state from the RemoteForm's issues. This is useful after a server round-trip that returns validation errors. |
Sources: packages/remotes/README.md:18-25, packages/remotes/src/lib/validation.svelte.ts:185-193, packages/remotes/CHANGELOG.md:7-9
Internal Logic & Flow
State Management
At its core, createValidation maintains a reactive $state object named issues. This object mirrors the structure of the form data, holding arrays of error strings for each field.
// packages/remotes/src/lib/validation.svelte.ts:4-6
type ValidationIssues = {
[key: string]: string[] | null | ValidationIssues
}
// packages/remotes/src/lib/validation.svelte.ts:15
let issues = $state<ValidationIssues>({})
Helper functions setNestedValue and getNestedValue are used to interact with this state object using dot-notation paths, allowing for support of nested form fields like address.state.
Sources: packages/remotes/src/lib/validation.svelte.ts:15, 20-40, 45-55
Event Handling
The fields(path) method is the primary way to connect the validation logic to your HTML inputs. It returns onblur and oninput handlers.
This sequence diagram illustrates the onblur validation flow.
This sequence diagram illustrates the oninput issue-clearing flow.
Usage Example
To use the validation, spread the handlers from valid.fields() onto an input and use valid.issues() to conditionally apply styles or display error messages.
<script lang="ts">
import { createValidation } from '@opensky/remotes';
import { myForm } from './myForm.remote';
import { z } from 'zod';
const schema = z.object({ name: z.string().min(4) });
const valid = createValidation(myForm);
</script>
<form {...myForm.preflight(schema).enhance( ... )}>
<input
{...myForm.fields.name.as('text')}
{...valid.fields('name')}
class:error={valid.issues('name')}
/>
{#if valid.issues('name')}
{#each valid.issues('name') as issue}
<p class="error">{issue}</p>
{/each}
{/if}
</form>
Sources: packages/remotes/README.md:27-37, 126-150
Integration with createEnhancedForm
While createValidation can be used standalone, it is designed to integrate seamlessly with createEnhancedForm. You can pass the validation instance to createEnhancedForm via the validation option.
When integrated, createEnhancedForm will automatically call validation.updateIssues() and validation.validateAll() at the appropriate stages of the form submission lifecycle.
validation.updateIssues()is called on anonIssuesevent (when the server returns validation errors without running the function).validation.validateAll()is called on anonErrorevent (when the submission promise rejects).
This automates the process of populating server-side validation errors into the UI.
The following flowchart shows how createEnhancedForm uses the validation instance.
Summary
createValidation is a powerful utility for creating a smooth and intuitive form validation experience in SvelteKit applications. By handling the logic for when to show and hide validation messages, debouncing server calls, and integrating with createEnhancedForm, it abstracts away common complexities and allows developers to focus on defining their validation rules. Its API provides both automated event handling via fields() and manual control via methods like addIssue() and validateAll().
Sources: packages/remotes/README.md:3-11, packages/remotes/src/lib/validation.svelte.ts:10-14