Server Actions (Mutations)
Server Actions let a form change server data by calling a server function directly — no separate API needed.
What you will learn
- Explain what a Server Action is
- Write a function with use server
- Wire a form to a Server Action
The normal way to change data
To save form data you usually build an API endpoint, then write browser code to fetch it with a POST. That is two pieces to keep in sync. Server Actions remove the middle step: you write one server function and call it straight from a form.
Marking a function as a Server Action
A Server Action is a function with the string use server as its first line. It always runs on the server, so it can safely touch a database. You can hand it directly to a form action.
// app/new-task/page.js (a Server Component)
export default function NewTaskPage() {
async function createTask(formData) {
'use server';
const title = formData.get('title');
// ...save the task to a database here...
console.log('Saved task:', title);
}
return (
<form action={createTask}>
<input name="title" placeholder="New task" />
<button type="submit">Add</button>
</form>
);
}Note: Output (server log after submitting "Buy milk"): Saved task: Buy milk The form called createTask on the server with the typed value. No fetch, no API route, no JSON wiring — Next.js handled the round trip for you.
The whole form flow, step by step
A Server Action quietly handles the full create-and-refresh journey for you. Here is exactly what happens, in order, when a user types "Buy milk" and clicks Add:
- The user types "Buy milk" into the input and clicks the Add button (which submits the form).
- Because the form has
action={createTask}, Next.js gathers the form fields into aformDataobject and sends them to the server — you write nofetchcode for this. - On the server,
createTask(formData)runs. Theuse serverline is what marks it safe to run there. - Inside the function,
formData.get('title')pulls out the typed value, "Buy milk". - Validate the value (is it empty? too long?), then save it — for example, insert it into a database. Here we just
console.logit. - To show the new task right away, you can call
revalidatePath('/tasks')so Next.js rebuilds that page with the fresh data and the user sees their new task appear.
| Step | Route handler way | Server Action way |
|---|---|---|
| Write server code | A route.js endpoint | One use server function |
| Call it from the form | fetch with POST | Pass it to action={...} |
| Pieces to keep in sync | Two | One |
After changing data, you often want the page to show the new state. Next.js gives helpers like revalidatePath('/tasks') to refresh a page so the new data appears right away.
Tip: Server Actions shine for forms and mutations (create, update, delete). For read-only data you fetch in a Server Component; for changing data, reach for a Server Action.
Watch out: Because the action runs on the server, never trust the input blindly — validate formData values before saving, just as you would in any backend.
Q. What is the main benefit of a Server Action?
✍️ Practice
- Write a Server Action that logs a submitted name to the server console.
- Add a second input (e.g. priority) and read both values from
formData.
🏠 Homework
- Build an "add comment" form wired to a Server Action that reads the comment text from formData.