TL;DR
Client-side validation improves UX by giving instant feedback, but it's NOT security. Use it for user experience, but always duplicate validation server-side. These prompts help you build accessible, helpful form validation with libraries like Zod, React Hook Form, or native HTML5.
React Hook Form + Zod
Use this prompt to set up form validation with React Hook Form and Zod. Your AI will generate a complete signup form component with a typed schema, real-time validation on blur, error messages, and loading state handling.
Form Validation Setup
Set up form validation with React Hook Form and Zod.
Install: npm install react-hook-form @hookform/resolvers zod
Create schema: const signupSchema = z.object({ email: z.string().email('Please enter a valid email'), password: z.string() .min(8, 'Password must be at least 8 characters') .regex(/A-Z/, 'Password must contain uppercase letter') .regex(/0-9/, 'Password must contain a number'), confirmPassword: z.string() }).refine(data => data.password === data.confirmPassword, { message: "Passwords don't match", path: 'confirmPassword' });
Use in component: const { register, handleSubmit, formState: { errors } } = useForm({ resolver: zodResolver(signupSchema) });
Show me the complete component with:
- Real-time validation on blur
- Error messages under each field
- Disabled submit until valid
- Loading state during submission
HTML5 Native Validation
Copy this prompt to enhance your forms with HTML5 native validation attributes. Your AI will add required, pattern, minlength, and type constraints to your markup along with custom JavaScript validation and CSS styling for invalid fields.
Native Form Validation
Improve my forms with HTML5 native validation.
Native attributes:
- required: Field must have value
- type="email": Must be valid email format
- type="url": Must be valid URL
- minlength/maxlength: Character limits
- min/max: Number range
- pattern: Custom regex
Example:
Custom validation with JavaScript: input.setCustomValidity('Custom error message'); input.reportValidity();
Style invalid fields: input:invalid { border-color: red; }
Client validation is for UX only: Never rely on it for security. Attackers can disable JavaScript, modify requests, or call your API directly. Server-side validation is mandatory.
Accessible Error Messages
This prompt asks your AI to make your form validation fully accessible. You'll get ARIA attributes, focus management on submit errors, screen reader announcements, and error messages that don't rely on color alone.
Accessible Validation UX
Make my form validation accessible to all users.
Accessibility requirements:
- Error messages linked with aria-describedby
- aria-invalid="true" on invalid fields
- Focus management - focus first error on submit
- Screen reader announcements for errors
- Don't rely on color alone (use icons/text too)
Example:
{errors.email && (
{errors.email.message}
)}
On form submit with errors:
- Prevent submission
- Show error summary at top
- Focus the error summary or first invalid field
- Announce "Form has X errors" to screen readers
Real-Time Validation Patterns
Use this prompt to implement user-friendly validation timing that avoids annoying users. Your AI will generate validate-on-blur logic, touched-field tracking, debounced async validation, and conditional error display.
Validation Timing
Implement user-friendly validation timing.
Best practices:
- Don't validate on every keystroke (annoying)
- Validate on blur (leaving field)
- Re-validate on change after first error shown
- Validate all on submit attempt
Implementation: const touched, setTouched = useState({}); const errors, setErrors = useState({});
// Validate on blur const handleBlur = (field) => { setTouched({ ...touched, field: true }); validateField(field); };
// Only show error if field touched {touched.email && errors.email && ( {errors.email} )}
Debounce for expensive validations: const debouncedValidate = useMemo( () => debounce(validateUsername, 300), );
// Check username availability after typing stops debouncedValidate(e.target.value)} />
Pro tip: Share validation schemas between frontend and backend. With Zod, you can define once and use in both React Hook Form and your API routes, ensuring consistency.
Should I disable the submit button until form is valid?
It's a UX preference. Disabled buttons can confuse users who don't see errors. An alternative is to allow submission, then show all errors at once with focus on the first error.
How do I validate async (like checking if username exists)?
Use debounced validation on change/blur. Show a loading spinner while checking. Cache results to avoid repeated API calls for the same value.
Further Reading
Want to understand the vulnerability before fixing it? These guides explain what's happening and why.
Audit Your Forms
Scan your forms for validation and security gaps.