Next.js Server Actions allow developers to write server-side mutation functions called directly from client forms or UI events without building manual API endpoints.
Server Actions are declared by adding the 'use server' directive at the top of an async function body or file module.
flowchart TD
A["User Submits Form"] --> B["Server Action Called ('use server')"]
B --> C["Execute DB Mutation on Server"]
C --> D["Call revalidatePath('/dashboard')"]
D --> E["UI Refreshes Automatically"]
Create a Server Action file to encapsulate server mutation logic cleanly:
// app/actions/userActions.ts
'use server';
import { revalidatePath } from 'next/cache';
export async function createUser(formData: FormData) {
const name = formData.get('name') as string;
const email = formData.get('email') as string;
// Insert record directly into database
await fetch('https://api.example.com/users', {
method: 'POST',
body: JSON.stringify({ name, email }),
headers: { 'Content-Type': 'application/json' },
});
// Revalidate cache to refresh list view immediately
revalidatePath('/users');
}
Pass Server Actions directly to HTML form action properties:
// app/users/NewUserForm.tsx
import { createUser } from '@/app/actions/userActions';
export default function NewUserForm() {
return (
<form action={createUser} className="space-y-4 p-4 border rounded">
<div>
<label className="block text-sm font-medium">Name</label>
<input type="text" name="name" required className="border p-2 rounded w-full" />
</div>
<div>
<label className="block text-sm font-medium">Email</label>
<input type="email" name="email" required className="border p-2 rounded w-full" />
</div>
<button type="submit" className="px-4 py-2 bg-blue-600 text-white rounded">
Save User
</button>
</form>
);
}
useFormStatusUse the useFormStatus React hook to show pending spinners while Server Actions process:
// app/users/SubmitButton.tsx
'use client';
import { useFormStatus } from 'react-dom';
export default function SubmitButton() {
const { pending } = useFormStatus();
return (
<button
type="submit"
disabled={pending}
className="px-4 py-2 bg-blue-600 text-white rounded disabled:bg-gray-400"
>
{pending ? 'Saving Record...' : 'Save Record'}
</button>
);
}
Next.js Server Actions eliminate boilerplate API routing code. Directly connecting forms to type-safe server functions streamlines data mutations in full-stack applications.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With