0
0
NextjsHow-ToBeginner · 4 min read

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 function and '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() from next/navigation to 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.