Server Actions to server functions
A Server Action is a function the framework turns into an endpoint and a form handler.
A Server Action is a function the framework turns into an endpoint and a form handler. In Dusk the endpoint is
explicit: serverFn(options, handler) in an exported binding, or an async function with "use server". The function
addComment above is the whole server side. The client calls it like a local function (the browser build holds a
stub), and the page refreshes with router.invalidate(), which reloads the loaders of the current location.
jsx
// app/actions.ts (Next.js)
"use server";
export async function addComment(formData) {
await db.addComment(formData.get("postId"), formData.get("text"));
revalidatePath("/posts/[id]");
}
| Next.js Server Action | Dusk server function |
|---|---|
Input is FormData or any serializable value |
Any value the wire format carries: JSON plus Date, Map, Set, BigInt, undefined. Functions and class instances throw a TypeError in the browser |
| No validation | input: takes any Standard Schema; invalid input answers 400 with at most 20 issues, ValidationError on the server, HttpError with data.issues in the browser |
| Always POST | POST by default; method: "GET" for safe reads (payload in the query string, 4096 characters) |
| Closures over server variables | Not allowed: a "use server" function inside a component cannot use variables of the enclosing function (build error SERVER_FN_CLOSURE_CAPTURE); pass them as arguments |
revalidatePath, revalidateTag |
router.invalidate() in the browser after the call. Nothing is cached on the server |
redirect() in an action |
throw redirect("/x"); the browser receives the redirect and follows it (same origin only) |
cookies().set() |
getRequestEvent().cookies.set(...) |
useActionState, useFormStatus, useOptimistic |
None. Keep pending and error state in signals, as the component above does. Optimistic updates are a signal you set before the call and roll back on error |
<form action={fn}> works without JavaScript |
form: true makes the endpoint accept application/x-www-form-urlencoded and multipart/form-data posts and answer 303 back to the page. The id is not available to server code, so a <form action> cannot be written without hard-coding /_dusk/fn/<id>; the supported client path is onSubmit |
| Errors | A thrown HttpError(4xx) reaches the caller with its message; any other error is Internal Server Error and goes to onError with a request id |
| CSRF | Checked by the handler: Sec-Fetch-Site or Origin, plus the x-dusk-fn header |
The "use server" directive is available when you prefer it: file level (every export must be an async function) or
function level. The build rewrites both to the same registration; see
server functions.