Using Server Actions in forms in Next.js
From the Next.js cheat sheet · Server Actions · verified Jul 2026
Using Server Actions in forms
typescript
// Simple form with Server Action
import { createPost } from '@/app/actions'
export default function CreatePostForm() {
return (
<form action={createPost}>
<input
type="text"
name="title"
placeholder="Post title"
required
/>
<textarea
name="content"
placeholder="Post content"
required
/>
<button type="submit">Create Post</button>
</form>
)
}
// With pending state
'use client'
import { useFormStatus } from 'react-dom'
import { createPost } from '@/app/actions'
function SubmitButton() {
const { pending } = useFormStatus()
return (
<button type="submit" disabled={pending}>
{pending ? 'Creating...' : 'Create Post'}
</button>
)
}
export default function FormWithStatus() {
return (
<form action={createPost}>
<input name="title" />
<textarea name="content" />
<SubmitButton />
</form>
)
}
// With form state and validation
'use client'
import { useActionState } from 'react'
import { createPostValidated } from '@/app/actions'
const initialState = {
errors: {},
message: null,
}
export default function FormWithValidation() {
const [state, formAction] = useActionState(createPostValidated, initialState)
return (
<form action={formAction}>
<div>
<input name="title" />
{state?.errors?.title && (
<p className="error">{state.errors.title}</p>
)}
</div>
<div>
<textarea name="content" />
{state?.errors?.content && (
<p className="error">{state.errors.content}</p>
)}
</div>
<button type="submit">Create Post</button>
</form>
)
}💡 Works with native form action attribute
⚡ Progressive enhancement without JS
📌 useFormStatus for pending states
🟢 useActionState for form state management