Skip to Content
use-server-action 1.0 is released 🎉
Getting Started

Getting Started

Installation

npm install use-server-action

Basic Setup

1. Create a Server Action

Create a server action using the serverAction wrapper. This automatically handles errors and returns a standardized result.

app/actions.ts
"use server"; import { serverAction, HandledError } from "use-server-action/server"; export const createUserAction = serverAction(async (name: string) => { if (!name.trim()) { // Use HandledError to surface a specific message to the client. // Plain Error throws result in a generic "An unexpected error occurred". throw new HandledError("Name is required", "VALIDATION_ERROR"); } const user = await db.user.create({ data: { name } }); return user; });

2. Use in a Client Component

Use the useServerAction hook to execute the action and track its state.

app/components/CreateUserForm.tsx
"use client"; import { useServerAction } from "use-server-action"; import { createUserAction } from "../actions"; export function CreateUserForm() { const { execute, data, error, isPending, isSuccess, isError, reset, } = useServerAction({ action: createUserAction, onSuccess: (user) => { console.log("User created:", user); }, onError: (message, code) => { console.error(`Error [${code}]:`, message); }, }); return ( <form action={(formData) => execute(formData.get("name") as string)}> <input name="name" placeholder="Name" disabled={isPending} /> <button type="submit" disabled={isPending}> {isPending ? "Creating..." : "Create User"} </button> {isError && <p className="error">{error}</p>} {isSuccess && <p className="success">Created: {data?.name}</p>} </form> ); }

Manual Error Handling

For more control over error responses, you can use success() and error() helpers directly:

app/actions.ts
"use server"; import { success, error } from "use-server-action/server"; export async function deleteUserAction(id: string) { try { await db.user.delete({ where: { id } }); return success({ deleted: true }); } catch (e) { return error("Failed to delete user", "DELETE_FAILED"); } }

Using executeAsync

If you need to await the result directly (e.g., for form handling or chaining actions), use executeAsync:

const { executeAsync } = useServerAction({ action: createUserAction }); async function handleSubmit(formData: FormData) { const result = await executeAsync(formData.get("name") as string); if (result.ok) { router.push(`/users/${result.data.id}`); } }

Next Steps

Last updated on