| name | safe-action-advanced |
| description | Use when working with bind arguments, metadata schemas, framework errors (redirect/notFound/forbidden/unauthorized), type inference utilities (InferSafeActionFnInput/Result), or server-level action callbacks |
next-safe-action Advanced Features
Overview
| Feature | Use Case |
|---|
| Bind arguments | Pass extra args to actions via .bind() (e.g., resource IDs) |
| Metadata | Attach typed metadata to actions for use in middleware |
| Framework errors | Handle redirect, notFound, forbidden, unauthorized in actions |
| Type utilities | Infer types from action functions and middleware |
Server-Level Action Callbacks
The second argument to .action() accepts callbacks that run on the server (not client-side hooks):
export const createPost = authActionClient.inputSchema(schema).action(
async ({ parsedInput, ctx }) => {
const post = await db.post.create(parsedInput);
return post;
},
{
onSuccess: async ({ data, parsedInput, ctx, metadata, clientInput }) => {
await invalidateCache("posts");
},
onError: async ({ error, metadata, ctx, clientInput, bindArgsClientInputs }) => {
await logError(error);
},
onSettled: async ({ result }) => {
await recordMetrics(result);
},
onNavigation: async ({ navigationKind }) => {
console.log("Navigation:", navigationKind);
},
},
);
These are distinct from hook callbacks (useAction({ onSuccess })) — server callbacks run in the Node.js runtime, hook callbacks run in the browser.
throwServerError
Re-throw server errors instead of returning them as result.serverError:
export const myAction = actionClient.inputSchema(schema).action(serverCodeFn, {
throwServerError: true,
});