Getting Started
Installation
npm install use-server-actionBasic 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
- Learn about useServerAction hook options
- Explore server utilities for creating actions
- Add middleware for auth, validation, and logging
Last updated on