Form Validation
Zod schema validation for forms and API inputs.
Creator uses Zod for form validation. Schemas are defined in lib/schemas/ and shared between client-side forms (via react-hook-form + @hookform/resolvers) and server-side API routes.
Schema files
| File | What it validates |
|---|---|
auth.ts | Login, signup, forgot password, reset password, OTP |
profile.ts | Profile name, email change, avatar upload, password change |
contact.ts | Contact form (name, email, message) |
notifications.ts | Notification preferences (boolean toggles) |
Shared field validators
lib/schemas/auth.ts exports reusable field validators that are imported by other schemas:
import { nameField, emailField, passwordField } from "@/lib/schemas/auth";| Field | Rules |
|---|---|
nameField | 1-64 characters, trimmed |
emailField | Valid email format, trimmed |
passwordField | 8-72 characters, at least one uppercase letter and one number |
Using schemas in forms
Schemas integrate with react-hook-form via the Zod resolver:
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { loginSchema, type LoginValues } from "@/lib/schemas/auth";
const form = useForm<LoginValues>({
resolver: zodResolver(loginSchema),
defaultValues: { email: "", password: "" },
});Using schemas in API routes
Parse and validate the request body on the server side:
import { contactSchema } from "@/lib/schemas/contact";
export async function POST(request: NextRequest) {
const body = await request.json();
const result = contactSchema.safeParse(body);
if (!result.success) {
return NextResponse.json(
{ error: result.error.issues[0].message },
{ status: 400 }
);
}
const { name, email, message } = result.data;
// ... handle validated data
}File upload validation
Avatar uploads use Zod's refine for custom validation. The limits are defined in config/file-upload-config.ts:
import { avatarSchema } from "@/lib/schemas/profile";
const result = avatarSchema.safeParse({ image: file });- Max file size: 3MB
- Allowed types: JPG, PNG
Adding a new schema
Create a new file in lib/schemas/ or add to an existing one. Export the schema and its inferred type:
import { z } from "zod";
export const mySchema = z.object({
title: z.string().min(1, "Title is required.").max(100),
description: z.string().optional(),
});
export type MyValues = z.infer<typeof mySchema>;Use it in your form with zodResolver(mySchema) and in your API route with mySchema.safeParse(body).