home / skills / hoangnguyen0403 / agent-skills-standard / server-actions
This skill helps you implement and secure Next.js Server Actions for server mutations, form handling, and RPC-style calls without extra endpoints.
npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill server-actionsReview the files below or copy the command above to add this skill to your agents.
---
name: Next.js Server Actions
description: Mutations, Form handling, and RPC-style calls.
metadata:
labels: [nextjs, actions, mutations]
triggers:
files: ['**/actions.ts', '**/*.tsx']
keywords: [use server, Server Action, revalidatePath, useFormStatus]
---
# Server Actions
## **Priority: P1 (HIGH)**
Handle form submissions and mutations without creating API endpoints.
## Implementation
- **Directive**: Add `'use server'` at the top of an async function.
- **Usage**: Pass to `action` prop of `<form>` or invoke from event handlers.
```tsx
// actions.ts
'use server';
export async function createPost(formData: FormData) {
const title = formData.get('title');
await db.post.create({ title });
revalidatePath('/posts'); // Refresh UI
}
```
## Client Invocation
- **Form**: `<form action={createPost}>` (Progressive enhancements work without JS).
- **Event Handler**: `onClick={() => createPost(data)}`.
- **Pending State**: Use `useFormStatus` hook (must be inside a component rendered within the form).
## **P1: Operational Standard**
### **1. Secure & Validate**
Always validate inputs and authorization within the action.
```tsx
'use server';
export async function updateProfile(prevState: any, formData: FormData) {
const session = await auth();
if (!session) throw new Error('Unauthorized');
const validatedFields = ProfileSchema.safeParse(
Object.fromEntries(formData.entries()),
);
if (!validatedFields.success)
return { errors: validatedFields.error.flatten().fieldErrors };
// mutation...
revalidatePath('/profile');
return { success: true };
}
```
### **2. Pending States**
Use `useActionState` (React 19/Next.js 15+) for state handling and `useFormStatus` for button loading states.
## **Constraints**
- **Closures**: Avoid defining actions inside components to prevent hidden closure encryption overhead and serialization bugs.
- **Redirection**: Use `redirect()` for success navigation; it throws an error that Next.js catches to handle the redirect.
This skill documents practical patterns for using Next.js Server Actions to handle mutations, form submissions, and RPC-style calls without separate API routes. It emphasizes secure validation, predictable state handling, and operational constraints to avoid common pitfalls. Follow these guidelines to implement server-side actions that are efficient, safe, and compatible with progressive enhancement.
Server Actions are ordinary async functions marked with the 'use server' directive that run on the server when invoked from a form or client event. Attach an action to a <form> via its action prop or call it from event handlers; use hooks like useFormStatus or useActionState to surface pending states. Actions can read FormData, perform mutations, revalidate paths, and use redirect() for navigation.
Can Server Actions run without client JavaScript?
Yes. When attached to a form via the action prop, Server Actions support progressive enhancement and will work with standard form submissions without client JS.
Where should I define my actions?
Define actions at module scope in separate files or modules. Avoid declaring them inside components to prevent closure serialization bugs and runtime overhead.
How do I handle loading states in forms?
Use useFormStatus inside a component rendered within the form to get pending state for buttons. For broader state, use useActionState (React 19 / Next.js 15+).