Progressive Enhancement with the form Action Prop
Wire forms to Server Actions so they work without JavaScript and enhance once hydrated.
Forms That Work Without JavaScript
Progressive enhancement means a form works using plain HTML first, then gets better once JavaScript loads and React hydrates.
In Next.js 15 App Router, you achieve this by passing a Server Action directly to a form's action prop. The browser can submit the form natively to the server before any client JS arrives.
- No JS yet? The form still posts and the server responds.
- JS hydrated? React intercepts the submit and uses
fetchunder the hood, avoiding a full page reload.
What a Server Action Looks Like
A Server Action is an async function marked with the 'use server' directive. It runs only on the server.
When passed to <form action={...}>, Next.js wires it up so the form's fields arrive as FormData.
// app/actions.ts
'use server'
export async function createPost(formData: FormData) {
const title = formData.get('title') as string
const body = formData.get('body') as string
// ...persist to your database here
console.log('Saving:', { title, body })
}All lessons in this course
- Progressive Enhancement with the form Action Prop
- Pending and Loading States with useFormStatus
- Field-Level Validation Errors with useActionState
- Instant Feedback Using useOptimistic