# Zod Next.js Integration > Validate Next.js server actions, API routes, and form data with Zod schemas ## When to Use - Validating inputs to Next.js server actions (App Router) - Parsing and validating request bodies in API route handlers - Handling form data validation with `useFormState` / `useActionState` - Validating search params and dynamic route segments ## Instructions 1. Validate server action inputs — the action receives `FormData` or typed arguments: ```typescript 'use server'; import { z } from 'zod'; import { redirect } from 'next/navigation'; const CreatePostSchema = z.object({ title: z.string().min(1, 'Title is required').max(100), content: z.string().min(10, 'Content is too short'), published: z.coerce.boolean().default(false), }); export async function createPost(formData: FormData) { const result = CreatePostSchema.safeParse({ title: formData.get('title'), content: formData.get('content'), published: formData.get('published'), }); if (!result.success) { return { success: false, errors: result.error.flatten().fieldErrors }; } const post = await db.post.create({ data: result.data }); redirect(`/posts/${post.id}`); } ``` 2. Use `useActionState` (React 19) or `useFormState` with typed state: ```typescript 'use client' import { useActionState } from 'react' import { createPost } from './actions' type FormState = { success: boolean errors?: { title?: string[]; content?: string[] } } const initialState: FormState = { success: false } export function CreatePostForm() { const [state, formAction, isPending] = useActionState(createPost, initialState) return (
{state.errors?.title &&

{state.errors.title[0]}

}