Next.js 13 - Use Server Action to submit form data

Next.js 13 introduces a new feature called Server Actions. It is built on top of React Actions.

Server Actions are a way to run code on the server when a user performs an action on the client.

For example, when a user submits a form, you can run code on the server to process the form data.

In this article, we will learn how to use Server Actions to submit form data.

Let's create a new Next.js app using the following command:

npx create-next-app@latest

Enable the experimental server actions feature by adding the following code to the next.config.js file:

const nextConfig = {
  experimental: {
    serverActions: true,
  },
};

Create a new page with a signup form at app/signup/page.tsx with the following code:

export default function SignupPage() {
  return (
    <form method="POST">
      <input type="text" name="name" />
      <input type="email" name="email" />
      <input type="password" name="password" />
      <button type="submit">Create Account</button>
    </form>
  );
}

This page can be accessed at /signup.

Now you can add a function within the page component to handle the form submission. This function will be called when the user submits the form.

export default function SignupPage() {
  const createAccount = async (formData: FormData) => {
    "use server";

    const name = formData.get("name");
    const email = formData.get("email");
    const password = formData.get("password");

    // Validate the form data and save it to the database

    console.log({ name, email, password });
  };

  // Form code
}

The use server directive makes sure that this function is only executed on the server.

Within the createAccount function, we can access the form data using the FormData API. We can then process the form data and save it to the database.

Let's use this function to handle the form submission by adding the action attribute to the form element:

<form action={createAccount} method="POST">
  ...
</form>

Here is the complete code for the page component:

export default function SignupPage() {
  const createAccount = async (formData: FormData) => {
    "use server";

    const name = formData.get("name");
    const email = formData.get("email");
    const password = formData.get("password");

    console.log({ name, email, password });
  };

  return (
    <form action={createAccount} method="POST">
      <input type="text" name="name" />
      <input type="email" name="email" />
      <input type="password" name="password" />
      <button type="submit">Create Account</button>
    </form>
  );
}