What Are Server Actions

Functions Marked 'use server'

A Server Action is an async function that runs on the server but can be called from a form or a Client Component. Next.js creates a hidden POST endpoint for it. You no longer write a separate API route just to save a form.

app/products/new/page.tsx

import { redirect } from 'next/navigation';
import { prisma } from '@/lib/prisma';

export default function NewProductPage() {
  async function createProduct(formData: FormData) {
    'use server';
    const name = String(formData.get('name'));
    const price = Number(formData.get('price'));
    const product = await prisma.product.create({ data: { name, price, stock: 0 } });
    redirect('/products/' + product.id);
  }

  return (
    <form action={createProduct}>
      <input name="name" placeholder="Product name" required />
      <input name="price" type="number" min="1" required />
      <button type="submit">Create</button>
    </form>
  );
}

Actions in Their Own File

Put 'use server' at the top of a file to make every export an action. Client Components can import these.

// app/cart/actions.ts
'use server';

import { cookies } from 'next/headers';
import { revalidatePath } from 'next/cache';
import { addItem } from '@/lib/cart';

export async function addToCart(productId: number, qty = 1) {
  const cartId = (await cookies()).get('cartId')?.value;
  if (!cartId) throw new Error('No cart');
  await addItem(cartId, productId, qty);
  revalidatePath('/cart');
}
'use client';
import { addToCart } from '@/app/cart/actions';

export default function AddButton({ id }: { id: number }) {
  return <button onClick={() => addToCart(id)}>Add to Cart</button>;
}

Security

Note: A Server Action is a public endpoint. Anyone can call it with any arguments. Always check the user session and validate input inside the action, exactly like an API route.

  • Forms with action work even before JavaScript loads (progressive enhancement).
  • Arguments and return values must be serializable.
  • Next.js checks the Origin header against the Host to block cross-site calls.