Skip to main content
Handling Form Validation with Zod

Handling Form Validation with Zod

Andrius LukminasAndrius LukminasDecember 18, 20254 min read248 views

Why Zod?

Zod provides runtime validation with TypeScript type inference. Define a schema once, get both validation and types.

Basic Pattern

import { z } from 'zod';

const createUserSchema = z.object({
  email: z.string().email('Invalid email address'),
  password: z.string().min(8, 'Password must be at least 8 characters'),
  name: z.string().min(2, 'Name is required'),
  role: z.enum(['CLIENT', 'DEVELOPER', 'MANAGER']),
});

// TypeScript type is inferred
type CreateUserInput = z.infer<typeof createUserSchema>;

API Validation

Every API endpoint validates input before processing:

export async function POST(request: NextRequest) {
  const body = await request.json();
  const validation = createUserSchema.safeParse(body);

  if (!validation.success) {
    return NextResponse.json(
      { error: 'Invalid input', details: validation.error.flatten() },
      { status: 400 }
    );
  }

  // validation.data is fully typed
  const user = await createUser(validation.data);
  return NextResponse.json({ user });
}

Client-Side Integration

We use React Hook Form with Zod resolver for form validation:

const form = useForm<CreateUserInput>({
  resolver: zodResolver(createUserSchema),
  defaultValues: { email: '', password: '', name: '', role: 'CLIENT' },
});

Benefits

  • Single source of truth for validation rules
  • Type-safe across client and server
  • Detailed error messages for users

Related Articles

Comments

0/5000 characters

Comments from guests require moderation.