How to Use Server Action with Form in Next.js
In Next.js, use
server actions by exporting an async function marked with 'use server' directive and call it from a form's action attribute. This lets the form submit data directly to the server without client-side JavaScript, simplifying server-side logic.Syntax
To use a server action with a form in Next.js, define an async function with the 'use server' directive. Then, assign this function to the form's action attribute. When the form submits, Next.js runs the server action on the server.
async function: The server action that handles form data.'use server': Directive to mark the function as a server action.form action={serverAction}: Connects the form submission to the server action.
tsx
export async function myServerAction(formData: FormData) { 'use server' const name = formData.get('name') // process data here } export default function MyForm() { return ( <form action={myServerAction}> <input name="name" type="text" /> <button type="submit">Submit</button> </form> ) }
Example
This example shows a simple form that sends a user's name to a server action. The server action logs the name and could save it or process it further. The form submits without client-side JavaScript.
tsx
import { redirect } from 'next/navigation' export async function submitName(formData: FormData) { 'use server' const name = formData.get('name')?.toString() || '' console.log('Received name:', name) // You can add database save or other logic here redirect('/thank-you') } export default function NameForm() { return ( <form action={submitName}> <label htmlFor="name">Name:</label> <input id="name" name="name" type="text" required /> <button type="submit">Send</button> </form> ) }
Output
Rendered form with label, input, and submit button; on submit, server logs name and redirects to /thank-you
Common Pitfalls
Common mistakes when using server actions with forms include:
- Not marking the function with
'use server', so it runs on the client instead of the server. - Trying to use client-side hooks or state inside the server action.
- Not handling form data correctly, such as forgetting to call
formData.get('fieldName'). - Expecting the server action to return JSX or client components; it should handle logic only.
tsx
/* Wrong: Missing 'use server' directive */ export async function wrongAction(formData: FormData) { // This will not run as a server action const data = formData.get('data') } /* Right: Correct server action */ export async function rightAction(formData: FormData) { 'use server' const data = formData.get('data') // process data }
Quick Reference
- Define server action with
async functionand'use server'directive. - Use
form action={serverAction}to connect form submission. - Access form fields with
formData.get('fieldName'). - Server actions run only on the server, no client hooks allowed.
- Use
redirect()fromnext/navigationto navigate after submission.
Key Takeaways
Mark server action functions with 'use server' to run them on the server.
Assign server actions directly to the form's action attribute for server-side form handling.
Use FormData methods to access submitted form values inside server actions.
Avoid client-side code inside server actions; keep them for server logic only.
Use Next.js navigation helpers like redirect() to handle post-submit navigation.