Forms & Validation
Relevant source files
The following files were used as context for generating this wiki page:
The Forms & Validation system provides a structured approach to capturing, validating, and submitting user data. It utilizes React Hook Form for client-side state management, Zod for schema definition, and Convex for backend persistence and error handling.
The system ensures data integrity through a multi-layered validation strategy:
- Client-side validation: Immediate feedback via Zod schemas and React Hook Form.
- Server-side validation: Re-validation within Server Actions before database mutation.
- Error Mapping: Transformation of Zod and Convex errors into user-friendly form field errors.
Sources: README.md:12-13, AGENTS.md:104-120
Architecture and Data Flow
The project follows a feature-based organization where form components, hooks, and schemas reside within specific domain directories. Forms typically use a useForm hook combined with a zodResolver to handle validation logic.
Form Submission Lifecycle
When you submit a form, the system follows a specific sequence to process data and handle potential errors.
This diagram illustrates the flow from initial user submission through client and server validation layers.
Sources: src/features/talks/actions/create-talk.ts:21-49, src/features/talks/hooks/use-talk-form.ts:223-238, src/features/users/components/register-form.tsx:75-96
Validation Components
The system relies on several core libraries and custom utilities to manage the form state and error reporting.
| Component | Responsibility | Source File |
|---|---|---|
React Hook Form | Manages form state, inputs, and submission lifecycle. | README.md:12 |
Zod | Defines data schemas and provides type-safe validation. | README.md:13 |
zodResolver | Bridges Zod schemas with React Hook Form. | src/features/talks/hooks/use-talk-form.ts:208 |
setServerErrors | Maps server-side error objects back to React Hook Form fields. | src/features/talks/actions/create-talk.ts:47 |
FieldError | Renders validation messages using Base UI primitives. | AGENTS.md:195-207 |
FieldError Requirements
When using the FieldError component with React Hook Form, you must pass the match prop. This ensures the component renders based on the external library's error state rather than native HTML5 validation.
Sources: AGENTS.md:195-207
// Correct implementation within a Field
{!!errors.email && (
<FieldError match>{errors.email.message}</FieldError>
)}
Sources: src/features/users/components/register-form.tsx:135-137
Server Actions and Mutations
Server Actions serve as the bridge between client forms and Convex backend functions. They perform final authorization checks and re-validate data using Zod.
Implementation Pattern
Actions use try/catch blocks to handle Convex mutation errors. The mapConvexErrorToFormErrors utility converts database-level errors into a format that setServerErrors can apply to the UI.
export async function createTalkAction(data: unknown) {
await requireAdminUser();
const parsed = talkFormSchema.safeParse(data);
if (!parsed.success) {
return { errors: mapZodErrors(parsed.error), success: false };
}
try {
const talkId = await fetchAuthMutation(api.talks.createTalk, parsed.data);
updateTag('talks'); // Invalidate Next.js cache
return { data: { talkId }, success: true };
} catch (error) {
return { errors: mapConvexErrorToFormErrors(error), success: false };
}
}
Sources: src/features/talks/actions/create-talk.ts:21-49, AGENTS.md:113-120
Specialized Form Behaviors
URL Change Detection
Specific forms, such as the Talk and Speaker edit forms, include logic to detect changes that would result in a URL path modification (e.g., slug or speaker changes).
- Detection: The
getUrlChangeInfoorgetUrlChangeForTalkhelper compares initial values against submitted values. - Confirmation: If a change is detected, a
UrlChangeDialogis presented to the user. - Execution: Submission only continues after the user confirms the potential impact on SEO/bookmarks.
Sources: src/features/talks/hooks/use-talk-form.ts:98-131, src/features/talks/components/edit-talk-sheet.tsx:112-120
Multi-Step Captcha Validation
The registration form integrates Cloudflare Turnstile for bot protection. The form logic prevents submission until a valid captcha token is generated and stored in the local component state.
Summary
Forms & Validation in this project provides a consistent developer experience by centralizing logic in Zod schemas and feature-specific hooks. By enforcing server-side re-validation and utilizing standardized error mapping utilities, the system maintains high data quality and provides clear feedback to users across all administrative and public entry points.
Sources: AGENTS.md:38-51, src/features/talks/hooks/use-talk-form.ts:223-238