createServerAction
The createServerAction function is returned by createClient and is used to define individual server actions in your application.
Each server action:
- Validates the input using a Zod schema
- Automatically applies shared middleware, context, and error handling defined in
createClient - Accepts optional
optionslikeclearto reset form state on error - Returns a structured
Responseobject compatible withuseActionStateon the client
Basic Usage
app/_lib/actions/sign-in.ts
"use server";
import { z } from "zod";
import { createServerAction } from "../utils/server-actions";
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
export const signIn = createServerAction<typeof schema>(
schema,
async (values) => {
// Your server-side logic here
return { ok: true };
}
);
Function Signature
function createServerAction<S extends ZodSchema, R = object>(
schema: S,
handler: (values: z.infer<S>, context: C) => Promise<Response<S, R>>,
options?: CreateServerActionOptions
): (
prev: Response<S, R>,
data: FormData
) => Promise<Response<S, R>>;
Parameters
schema: A Zod schema used to validate the incoming form data.handler: A function that receives the validated values and the context (if defined). It must return aResponseobject.options(optional):clear?: boolean– Iftrue(default), submitted form values will be cleared on error. Set tofalseto preserve user input after validation or middleware failure.
Return Type
Each server action returns a Response object:
export type Response<S extends ZodSchema, R = object> = {
ok: boolean;
message?: string | { title: string; description: string };
errors?: { [K in keyof z.infer<S>]?: string[] };
values?: Partial<z.infer<S>>;
response?: R;
};
Behavior
- If
ok: true, the action was successful. You may optionally return aresponseobject with any type-safe data. - If
ok: false, the response may contain: - A general
message(string or object with title/description) errorsfor field-level validation (from Zod)valuescontaining submitted form data, unlessclear: true(default) was applied
Examples
Custom Response
Return structured data when the action succeeds:
export const signIn = createServerAction<typeof schema, { url: string }>(
schema,
async (values) => {
return { ok: true, response: { url: "https://example.com/dashboard" } };
},
);
The response property is strongly typed as { url: string }.
Empty Response
If you don’t need to return additional data:
export const signIn = createServerAction<typeof schema>(
schema,
async (values) => {
return { ok: true };
},
);
Form-Level Error
Return a general message when submission fails:
export const signIn = createServerAction<typeof schema>(
schema,
async (values) => {
return { ok: false, message: "Invalid credentials" };
},
);
Preserve Form Values on Error
Use clear: false to keep the form populated after an error:
export const signIn = createServerAction<typeof schema>(
schema,
async () => {
return { ok: false, message: "Invalid credentials" };
},
{ clear: false }
);
By default, form values are cleared when an error occurs. This helps reset the form unless you explicitly disable it.
Middleware Handling
If you've defined a global middleware in createClient, and it returns a message:
middleware: async () => {
return { message: "Unauthorized access" };
}
Then this message will be returned by any server action, and the handler won't be executed:
{
ok: false,
message: "Unauthorized access",
values: {} // or original values if clear: false
}