A Server Function is an asynchronous function that runs on the server and can be called from the client through a network request.In an action or mutation context, they are also called Server Actions. By convention, a Server Action is an async function used with startTransition. This happens automatically when the function is:
Passed to a <form> using the action prop.
Passed to a <button> using the formAction prop.
When an action is invoked, Next.js can return both the updated UI and new data in a single server roundtrip. Behind the scenes, actions use the POST HTTP method.
Server Functions are reachable via direct POST requests, not only through your application’s UI. Always verify authentication and authorization inside every Server Function. See the Data Security guide for recommended patterns.
Use the 'use server' directive to create a Server Function. Place the directive at the top of an async function body, or at the top of a separate file to mark all exports.
import { auth } from '@/lib/auth'export async function createPost(formData: FormData) { 'use server' const session = await auth() if (!session?.user) { throw new Error('Unauthorized') } const title = formData.get('title') const content = formData.get('content') // Mutate data // Revalidate cache}export async function deletePost(formData: FormData) { 'use server' const session = await auth() if (!session?.user) { throw new Error('Unauthorized') } const id = formData.get('id') // Verify the user owns this resource before deleting // Mutate data // Revalidate cache}
Server Functions can be inlined directly in Server Components:
export default function Page() { async function createPost(formData: FormData) { 'use server' // ... } return <></>}
Server Components support progressive enhancement by default. Forms that call Server Actions will be submitted even if JavaScript has not loaded yet or is disabled.
React extends the HTML <form> element to allow a Server Function to be invoked with the action prop. The function automatically receives the FormData object:
Redirect the user to a different page after a mutation by calling redirect from next/navigation:
'use server'import { auth } from '@/lib/auth'import { revalidatePath } from 'next/cache'import { redirect } from 'next/navigation'export async function createPost(formData: FormData) { const session = await auth() if (!session?.user) { throw new Error('Unauthorized') } // Mutate data // ... revalidatePath('/posts') redirect('/posts')}
redirect throws a framework-handled exception. Any code after it will not execute. Call revalidatePath or revalidateTag before calling redirect if you need fresh data on the destination page.
Use the useEffect hook to invoke a Server Action when a component mounts or a dependency changes. This is useful for mutations that need to be triggered automatically, such as updating a view count: