Back to Articles
ReactApril 28, 202610 min read

Mastering Next.js Server Actions for Forms and Mutations


Server Actions are async functions that run on the server in Next.js App Router. They eliminate the need for API routes when handling form submissions and data mutations, keeping your server logic close to your components.

1. Defining a Server Action

Create a server action by marking a function with 'use server' at the top of a file or inline within a component.

'use server'

export async function createPost(formData: FormData) {
  const title = formData.get('title') as string;
  const body = formData.get('body') as string;

  await db.posts.create({ data: { title, body } });
  revalidatePath('/posts');
}

2. Validating Inputs with Zod

Always validate form data before processing. Zod schemas give you type-safe validation with clear error messages.

import { z } from 'zod';

const PostSchema = z.object({
  title: z.string().min(1).max(200),
  body: z.string().min(10),
});

export async function createPost(formData: FormData) {
  const parsed = PostSchema.safeParse({
    title: formData.get('title'),
    body: formData.get('body'),
  });
  if (!parsed.success) throw new Error('Invalid input');
  // ... save to database
}

3. Revalidating Cache After Mutations

Use revalidatePath or revalidateTag after a mutation to ensure the UI reflects the latest data from the server.

4. Progressive Enhancement

Server Actions work without JavaScript enabled in the browser. Forms submit directly to the server, and the response updates the page seamlessly when JS loads.