Building a Type-Safe API Layer in Next.js App Router With Zod and Server Actions A developer at pixova.io built a type-safe API layer for Next.js App Router using Zod validation and discriminated union types for Server Actions. The pattern ensures runtime validation, consistent error handling, and type safety across the client-server boundary, as demonstrated in the generation pipeline for the company's free AI wallpaper maker. Server Actions in Next.js App Router look deceptively simple — write an async function, mark it with 'use server' , call it from a Client Component. The surface area is small. The problems surface when you start thinking about validation, error handling, and type safety across the client-server boundary. Without a deliberate approach, you end up with untyped form data on the server, error handling that varies across actions, and client code that can't trust the shape of what comes back. Here's the pattern I landed on for type-safe Server Actions with Zod validation and consistent error handling, from building the generation pipeline powering the free AI wallpaper maker https://pixova.io/blog/ai-wallpaper-maker-free at pixova.io. The simplest Server Action works fine for prototypes: js 'use server'; export async function submitForm formData: FormData { const prompt = formData.get 'prompt' as string; // No validation, no type safety, any error handling is ad hoc const result = await generateImage prompt ; return result; } The issues: formData.get 'prompt' returns string | null | File — the as string cast hides a bug waiting to happenStart with a discriminated union for action results: // lib/types/action.ts export type ActionSuccess