Next.js

Verified against Claude Code · 2026-07-18

Build a Server Action form with real validation, not a client fetch call in disguise

Produces a form wired to a Server Action with schema validation, per-field errors, and useActionState-driven pending/error UI instead of hand-rolled loading state.

Claude CodeCursor 2.1v0 by Vercel

The prompt

Ready to copy — highlighted parts are example details you can swap.

<context>
Form fields: displayName (text, required), bio (textarea, optional, max 280 chars)
What the submission actually does (the mutation): Updates the current user's profile row in the database
Validation library preference: Zod
</context>

<task>
Build this as a real Server Action form: a <form action=(serverAction)> whose action prop is a function marked 'use server', not a client-side onSubmit handler that fetches an API route. Wire up pending and error state with useActionState (and useFormStatus for the submit button) instead of manual isLoading/error useState.
</task>

<requirements>
- Validate the submitted FormData against a schema server-side, inside the Server Action itself — never trust client-side validation alone, since the action can be invoked directly.
- Return field-level errors from the action in the shape useActionState expects, so each input can show its own error message instead of one generic banner.
- After a successful mutation, call revalidatePath (or revalidateTag) for whatever page/data this action affects, so the UI reflects the change without a manual client-side refetch.
- Keep the submit button disabled and showing a pending label via useFormStatus while the action is in flight — don't hand-roll this with a separate useState your Server Action has to remember to update.
- The form should still submit successfully with JavaScript disabled, since it's a real HTML form action — don't add anything (like preventDefault + fetch) that would break that.
</requirements>

<output_format>
Two files: the Server Action ('use server' function with validation), and the form component using useActionState/useFormStatus. Then one line confirming what gets revalidated on success.
</output_format>
Customize the highlighted detailsoptional — the prompt above already works

Why this works

The load-bearing distinction here is that a Server Action attached directly to a form's action prop is a real HTML form submission the browser can execute natively — that's what makes it work with JavaScript disabled, and it's also exactly the property a client-side onSubmit-plus-fetch reimplementation throws away for no benefit. Requiring server-side validation inside the action itself (not just in the client form) matters because a Server Action is a callable server endpoint the client can invoke directly, bypassing whatever validation lives in the form component. And routing pending/error state through useActionState and useFormStatus instead of hand-rolled useState removes an entire class of bugs where the loading spinner and the actual action state drift out of sync — the hook is wired directly to the action's lifecycle, not to a variable the developer has to remember to flip.

What you get back

Submitting a bio over 280 characters returns { errors: { bio: 'Must be 280 characters or fewer' } } from the action, which useActionState surfaces under the bio field specifically — the displayName field shows no error and its value is preserved. On success, revalidatePath('/profile') runs inside the action so the profile page shows the new bio immediately.

Verified against

Claude Code Sonnet 4.6 · 2026-07-18

v0 by Vercel 2026.6 · 2026-07-19

Changelog

  • 2026-07-18 Initial version, tested against Claude Code and v0 on React 19 / Next.js 16 forms.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All Next.js prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY