Skillshub nextjs-server-actions
Mutations, Form handling, and RPC-style calls. Use when implementing Server Actions, form mutations, or RPC-style data mutations in Next.js. (triggers: app/**/actions.ts, src/app/**/actions.ts, app/**/*.tsx, src/app/**/*.tsx, use server, Server Action, revalidatePath, useFormStatus)
git clone https://github.com/ComeOnOliver/skillshub
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/HoangNguyen0403/agent-skills-standard/nextjs-server-actions" ~/.claude/skills/comeonoliver-skillshub-nextjs-server-actions && rm -rf "$T"
skills/HoangNguyen0403/agent-skills-standard/nextjs-server-actions/SKILL.mdServer Actions
Priority: P1 (HIGH)
[!WARNING] If the project uses the
directory instead of the App Router, ignore this skill entirely.pages/
Handle form submissions and mutations without creating API endpoints.
Implementation Guidelines
-
Directive: Always start the file or function with
. Access'use server'
for typed form fields. Export async functions for mutations.formData.get('title') -
Form Handling: Use the
prop ofaction
to trigger actions via<form>
. Useaction={createPost}
foruseFormStatus()
states —pending
on buttons. Usedisabled={pending}
(React 19/Next.js 15) foruseActionState
form state withaction={action}
.<form action={action}> -
Data Refresh: Trigger UI updates using
orrevalidatePath('/')
after a successful mutation.revalidateTag('tag-name') -
Interactivity: For non-form triggers, invoke actions using the
hook to handle loading UI and prevent the page from blocking.useTransition -
Optimistic Updates: Use
to show the expected UI state immediately before the server confirms the mutation.useOptimistic -
Security: Sanitize all inputs from
. Perform auth checks inside every action (FormData
). Limit file uploads by size and MIME type.await auth() -
Form:
(Progressive enhancements work without JS).<form action={createPost}> -
Event Handler:
.onClick={() => createPost(data)} -
Pending State: Use
hook (must be inside a component rendered within the form).useFormStatus
P1: Operational Standard
1. Secure & Validate
Always validate inputs with
z.object({ schema and safeParse before processing. Check authorization within the action. See Secure Action Example.
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
for success navigation; it throws an error that Next.js catches to handle the redirect.redirect()
Anti-Patterns
- No unvalidated Server Action inputs: Always validate with Zod before processing.
- No skipped auth checks: Verify session/user inside every action, not just middleware.
- No actions defined inside components: Define in
to avoid closure bugs.actions.ts - No
in try/catch:redirect()
throws; catching it suppresses the redirect.redirect()