Async Function Marked "use server"
Server Actions — Run Server Code From the Client
A Server Action is an async function annotated with `'use server'`. The client calls it like a normal function; Next.js handles the RPC, security, and serialization.
What you'll learn
- Mark a function with `'use server'`
- Call it from a Client or Server Component
- Pass it as a form `action`
Server Actions replace the boilerplate of “make a route handler, write a fetch on the client, parse JSON, handle errors”. You write one async function; React and Next.js wire up the rest.
Defining an Action
A 'use server' directive can mark a whole module or an individual function.
// app/todos/actions.ts
'use server'
import { revalidatePath } from 'next/cache'
import { db } from '@/lib/db'
export async function addTodo(form: FormData) {
const text = String(form.get('text') ?? '')
if (!text) return
await db.todos.insert({ text })
revalidatePath('/todos')
} Everything in actions.ts runs on the server. The client only sees a function reference.
Wiring It to a Form
The simplest invocation is a plain HTML form:
// app/todos/page.tsx (server component)
import { addTodo } from './actions'
export default function Page() {
return (
<form action={addTodo}>
<input name="text" />
<button>Add</button>
</form>
)
} Submitting the form runs addTodo on the server, then revalidates /todos. No client
JavaScript required for the happy path.
Calling Directly From a Client Component
You can also call an action like any async function:
'use client'
import { addTodo } from './actions'
export function QuickAdd() {
return <button onClick={() => addTodo(new FormData())}>Add empty</button>
} Under the hood it is an HTTP POST to a Next-managed endpoint, but you do not see that.
Forms With Server Actions →