TheWidePoint
Web Dev 2025-06-10 6 min read TheWidePoint Team

Next.js Server Actions: The Complete Guide for 2025

Server Actions changed how we think about mutations in React. Here's everything you need to know to use them confidently.

Next.js Server Actions: The Complete Guide for 2025

Server Actions are one of the most exciting additions to Next.js. They let you write server-side code directly inside your components — no API routes needed for simple mutations.

What Are Server Actions?

A Server Action is an async function that runs on the server but can be called from the client. Next.js handles the serialisation, CSRF protection, and network layer automatically.

// app/actions.ts
"use server";

export async function createPost(formData: FormData) {
  const title = formData.get("title") as string;
  await db.posts.create({ data: { title } });
  revalidatePath("/blog");
}

Using Them in Forms

The cleanest pattern — pass the action directly to a <form>:

import { createPost } from "./actions";

export default function NewPostForm() {
  return (
    <form action={createPost}>
      <input name="title" placeholder="Post title" />
      <button type="submit">Create</button>
    </form>
  );
}

Progressive Enhancement

This works even with JavaScript disabled. The form falls back to a standard HTML form submission, and Next.js handles the rest. This is real progressive enhancement, not a polyfill.

Handling Errors and Loading State

Use useActionState (previously useFormState) to handle responses:

"use client";

import { useActionState } from "react";
import { createPost } from "./actions";

export default function NewPostForm() {
  const [state, action, isPending] = useActionState(createPost, null);

  return (
    <form action={action}>
      <input name="title" />
      {state?.error && <p className="text-red-500">{state.error}</p>}
      <button disabled={isPending}>
        {isPending ? "Creating..." : "Create Post"}
      </button>
    </form>
  );
}

When Not to Use Server Actions

  • For read operations — use fetch or server components directly
  • For complex multi-step flows — a traditional API route is clearer
  • When you need streaming responses — use Route Handlers

Conclusion

Server Actions are the right tool for mutations that don't need a dedicated API. They simplify your codebase, improve security, and enable progressive enhancement out of the box.