Server Actions — Run Server Code From the Client

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.

4 min read Level 3/5 #nextjs#server-actions#mutations
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 →