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)

install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
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"
manifest: skills/HoangNguyen0403/agent-skills-standard/nextjs-server-actions/SKILL.md
source content

Server Actions

Priority: P1 (HIGH)

[!WARNING] If the project uses the

pages/
directory instead of the App Router, ignore this skill entirely.

Handle form submissions and mutations without creating API endpoints.

Implementation Guidelines

  • Directive: Always start the file or function with

    'use server'
    . Access
    formData.get('title')
    for typed form fields. Export async functions for mutations.

  • Form Handling: Use the

    action
    prop of
    <form>
    to trigger actions via
    action={createPost}
    . Use
    useFormStatus()
    for
    pending
    states —
    disabled={pending}
    on buttons. Use
    useActionState
    (React 19/Next.js 15) for
    action={action}
    form state with
    <form action={action}>
    .

  • Data Refresh: Trigger UI updates using

    revalidatePath('/')
    or
    revalidateTag('tag-name')
    after a successful mutation.

  • Interactivity: For non-form triggers, invoke actions using the

    useTransition
    hook to handle loading UI and prevent the page from blocking.

  • Optimistic Updates: Use

    useOptimistic
    to show the expected UI state immediately before the server confirms the mutation.

  • Security: Sanitize all inputs from

    FormData
    . Perform auth checks inside every action (
    await auth()
    ). Limit file uploads by size and MIME type.

  • 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 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
    redirect()
    for success navigation; it throws an error that Next.js catches to handle the 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
    actions.ts
    to avoid closure bugs.
  • No
    redirect()
    in try/catch
    :
    redirect()
    throws; catching it suppresses the redirect.