Script Valley
Next.js: Full-Stack React Applications
API Routes and Server ActionsLesson 3.4

How to validate and sanitize data in Next.js Server Actions

Zod validation, schema parsing, safeParse, error handling in actions, type-safe FormData, input sanitization patterns

Never Trust FormData

FormData values are always strings. Users can send anything. Validate on the server before touching your database. Zod is the standard tool for this.

npm install zod
'use server'
import { z } from 'zod'

const PostSchema = z.object({
  title: z.string().min(1, 'Title required').max(100),
  content: z.string().min(10, 'Too short'),
  published: z.coerce.boolean().default(false),
})

export async function createPost(
  prevState: { errors: Record<string, string[]> | null },
  formData: FormData
) {
  const raw = {
    title: formData.get('title'),
    content: formData.get('content'),
    published: formData.get('published'),
  }

  const result = PostSchema.safeParse(raw)

  if (!result.success) {
    return { errors: result.error.flatten().fieldErrors }
  }

  await db.post.create({ data: result.data })
  revalidatePath('/blog')
  return { errors: null }
}

Displaying Field Errors

// In the Client Component:
{state.errors?.title && (
  <span className="text-red-500">{state.errors.title[0]}</span>
)}

Use safeParse (not parse) to avoid throwing. safeParse returns a result object you can inspect. flatten().fieldErrors gives you field-level error messages as arrays, perfect for displaying next to each input.

Up next

How to structure Next.js API routes for REST endpoints

Sign in to track progress

How to validate and sanitize data in Next.js Server Actions โ€” API Routes and Server Actions โ€” Next.js: Full-Stack React Applications โ€” Script Valley โ€” Script Valley