FrameworksNextjs
Next.js Server Actions
Implementing type-safe, progressively enhanced forms powered by React 19 and Next.js Server Actions.
Preview
Next.js Server Actions
Zero-API Server Action Form
Invoke server functions directly from your component with automated CSRF protection, optimistic transitions, and server-side state serialization.
Interactive responsive preview
Drag handles on right and bottom to resize
Overview
Next.js Server Actions allow you to run asynchronous server code directly from your components without writing boilerplate API route handlers. They seamlessly integrate with React transitions, support optimistic updates, and enforce server-side validation schemas.
Server Action Implementation
Define the server action in a dedicated file with the 'use server' directive:
// app/actions/create-project.ts
'use server';
import { z } from 'zod';
import { revalidatePath } from 'next/cache';
const projectSchema = z.object({
projectName: z.string().min(3, 'Project name must be at least 3 characters'),
region: z.enum(['us-east-1', 'eu-central-1', 'ap-southeast-1', 'auto']),
domain: z.string().optional(),
});
export async function createProjectAction(prevState: unknown, formData: FormData) {
const parsed = projectSchema.safeParse({
projectName: formData.get('projectName'),
region: formData.get('region'),
domain: formData.get('domain'),
});
if (!parsed.success) {
return {
status: 'error',
errors: parsed.error.flatten().fieldErrors,
};
}
try {
// Database or infrastructure provisioning
const project = await db.project.create({ data: parsed.data });
revalidatePath('/projects');
return { status: 'success', data: project };
} catch (error) {
return {
status: 'error',
message: 'Failed to provision namespace on cluster.',
};
}
}Component Integration with React Transitions
'use client';
import { useTransition, useState } from 'react';
import { createProjectAction } from '@/app/actions/create-project';
export default function ProjectForm() {
const [isPending, startTransition] = useTransition();
const [state, setState] = useState(null);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
startTransition(async () => {
const res = await createProjectAction(null, formData);
setState(res);
});
};
return (
<form onSubmit={handleSubmit}>
{/* input fields */}
<button type="submit" disabled={isPending}>
{isPending ? 'Provisioning...' : 'Deploy'}
</button>
</form>
);
}Benefits of Server Actions
- No API Route Overhead: Zero Route Handler files to create, route, or maintain.
- Built-in Security: Next.js automatically generates unique action IDs, cryptographic action tokens, and CSRF validations.
- Progressive Enhancement: Can execute even before client JavaScript hydration completes.
- Direct Cache Revalidation: Call
revalidatePath()orrevalidateTag()immediately following mutations.