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 receivesFormData. 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 optionallyredirect(). - 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
// 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:
// 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 receivesprevStatefirst, thenformData. A plain<form action={createPost}>receives onlyformData.
Quick reference
| Next.js | Angular |
|---|---|
'use server' action | Service method + HttpClient.post to a backend |
<form action={action}> | (ngSubmit) + reactive forms |
useActionState | FormControl validators + a pending signal |
redirect() in action | Router.navigate() after success |