Server Actions are async functions that run on the server, invoked from forms or client event handlers. Mark a function with 'use server' (at file or function level) to mutate data without hand-writing fetch boilerplate.
Form action pattern
// app/actions.ts
'use server';
export async function createTodo(formData: FormData) {
const title = formData.get('title') as string;
await db.todo.create({ data: { title } });
revalidatePath('/todos');
}
// app/todos/page.tsx
import { createTodo } from '../actions';
export default function Page() {
return (
<form action={createTodo}>
<input name="title" />
<button type="submit">Add</button>
</form>
);
}
Progressive enhancement
Forms work without JavaScript until you add client enhancements—good baseline for accessibility and resilience.
Security
Always validate and authorize on the server. Treat action inputs like any API payload—never trust the client.
Important interview questions and answers
- Q: Server Action vs API route?
A: Actions integrate with React forms and RSC; Route Handlers expose HTTP for arbitrary clients. - Q: Where does 'use server' go?
A: Top of a dedicated actions file or inline above the async function.
Self-check
- Why revalidate after a mutation?
- What type is
formDatain an action?
Challenge
Validate the action
- Extend the simulated action to reject empty titles.
- Print the error shape when validation fails.
Done when: terminal shows ok:false when title is blank.
Interview prep
- Server Action vs Route Handler?
Actions integrate with forms and RSC mutations; Route Handlers expose HTTP endpoints for webhooks and non-React clients.