Next.js: The React Framework (App Router)Entry 9 of 16

Server Actions and Forms

A Server Action is an async function marked 'use server' that runs on the server but can be called from a form or a Client Component, like a built-in API endpoint.

react.dev'use server'

Notes

  • Pass a Server Action to <form action={…}>; it receives FormData. The form works even before JavaScript loads.
  • useActionState (from React) tracks the action's returned state and pending status for validation messages.
  • After a mutation, refresh cached data (updateTag, revalidatePath) and optionally redirect().
  • Treat every Server Action as a public endpoint: validate input and check authorization inside it.

What / Why / When

What

Server functions callable from the UI without writing an API route.

Why

Less boilerplate, progressive enhancement, typed end to end.

When

Creating, updating, or deleting data from forms.

Use case

A "New post" form with validation.

Code compare

Next.js
// app/posts/new/actions.ts"use server";​import { redirect } from "next/navigation";import { updateTag } from "next/cache";​export type FormState = { error?: string };​export async function createPost(prevState: FormState, formData: FormData): Promise<FormState> {  const title = String(formData.get("title") ?? "").trim();  if (title.length < 3) return { error: "Title must be at least 3 characters." };​  await db.post.create({ data: { title } });  updateTag("posts"); // posts list shows the new post immediately  redirect("/posts");}

Angular has no server functions. The form posts to your backend through a service:

Angular
// post.service.ts (added method)createPost(title: string) {  return this.http.post<Post>(`${environment.apiUrl}/posts`, { title });}

Differences and gotchas

  • Next.js validates on the server inside the action; Angular validates on the client and your backend must validate again.
  • Next.js forms submit without JavaScript (progressive enhancement). Angular forms need the app to have hydrated.
  • useActionState's action receives prevState first, then formData. A plain <form action={createPost}> receives only formData.

Quick reference

Next.jsAngular
'use server' actionService method + HttpClient.post to a backend
<form action={action}>(ngSubmit) + reactive forms
useActionStateFormControl validators + a pending signal
redirect() in actionRouter.navigate() after success