Teaches client and server-side form validation patterns in React 19 with Server Actions. Use when implementing form validation, input checking, or error handling.
Teaches React 19 form validation patterns using both client-side HTML5 validation and server-side validation with Zod. Use when implementing forms that require input checking and error handling with Server Actions.
/plugin marketplace add djankies/claude-configs/plugin install react-19@claude-configsThis skill is limited to using the following tools:
React 19 forms require validation on both client and server.
Use HTML5 validation + custom logic:
<form action={submitForm}>
<input
name="email"
type="email"
required
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
/>
<input
name="age"
type="number"
min="18"
max="120"
required
/>
<button type="submit">Submit</button>
</form>
Always validate on server - client validation can be bypassed:
'use server';
import { z } from 'zod';
const schema = z.object({
email: z.string().email('Invalid email'),
age: z.number().min(18, 'Must be 18+').max(120),
password: z.string().min(8, 'Password must be 8+ characters'),
});
export async function registerUser(previousState, formData) {
const data = {
email: formData.get('email'),
age: Number(formData.get('age')),
password: formData.get('password'),
};
const result = schema.safeParse(data);
if (!result.success) {
return {
errors: result.error.flatten().fieldErrors,
};
}
try {
const user = await db.users.create({ data: result.data });
return { success: true, userId: user.id };
} catch (error) {
if (error.code === 'P2002') {
return { errors: { email: ['Email already exists'] } };
}
return { error: 'Registration failed' };
}
}
'use client';
import { useActionState } from 'react';
import { registerUser } from './actions';
export default function RegisterForm() {
const [state, formAction, isPending] = useActionState(registerUser, null);
return (
<form action={formAction}>
<div>
<input name="email" type="email" required />
{state?.errors?.email && (
<span className="error">{state.errors.email[0]}</span>
)}
</div>
<div>
<input name="age" type="number" required />
{state?.errors?.age && (
<span className="error">{state.errors.age[0]}</span>
)}
</div>
<div>
<input name="password" type="password" required />
{state?.errors?.password && (
<span className="error">{state.errors.password[0]}</span>
)}
</div>
<button type="submit" disabled={isPending}>
{isPending ? 'Registering...' : 'Register'}
</button>
{state?.error && <p className="error">{state.error}</p>}
{state?.success && <p>Registration successful!</p>}
</form>
);
}
Recommended: Zod for type-safe validation:
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
confirmPassword: z.string(),
}).refine(data => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ['confirmPassword'],
});
For comprehensive validation patterns, see: research/react-19-comprehensive.md.
Zod v4 Validation:
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
This skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.