EMZETT.
Login

Server Actions: forms without your own API (Next.js)

In short: Server Actions are functions that run on the server and are called directly from forms or components; they replace many hand-written API routes.

In more detail: Instead of building an API route for every form, you mark a function with "use server" and pass it as action to a <form>. On submit the browser calls the function on the server; Next.js handles the network call.

In Depth

Example

// actions.ts
"use server";
export async function save(formData: FormData) {
  const title = String(formData.get("title") ?? "");
  // validate, store, then refresh the page
}

<form action={save}> is enough. Thanks to progressive enhancement the form even works without JavaScript. After saving you refresh data with revalidatePath/revalidateTag or redirect with redirect.

Security: treat it like a public API

Every Server Action is an endpoint reachable over HTTP, even if it looks like a mere function call. So always:

  • Validate inputs (for example with Zod); TypeScript types do not exist at runtime.
  • Check sign-in and permission inside the function itself, not only in the UI.
  • Rate limiting for actions open to abuse.
  • Do not return secrets; keep error messages general.

State and feedback

  • useActionState provides the return value (for example error texts) and the pending state.
  • useFormStatus shows “Saving…” in buttons.
  • useOptimistic shows changes immediately before the server answers.
  • For file uploads and streaming, route handlers are sometimes better suited.

When to prefer an API route

If outside clients (mobile app, third parties, webhooks) should use the interface, a documented, versioned API makes sense. Server Actions are meant for your own UI and their addresses change at build time.

See also: Next.js App Router, Validating forms with Zod, CSRF