Course outline · 0% complete

0/29 lessons0%

Course overview →

Forms and server actions

lesson 6-1 · ~10 min · 19/29

Quiz

Warm-up from '[slug] routes and params': in current Next.js, how do you read the slug inside app/blog/[slug]/page.js?

Writing data without an API detour

So far every page only read data. Now users need to create things. In Backend with Node.js the recipe was: build a POST /api/posts endpoint, then have the frontend fetch it with a JSON body. Next.js offers a shortcut called a server action: a function marked "use server" that the framework exposes to forms automatically.

// app/actions.js
"use server";

export async function createPost(formData) {
  const title = formData.get("title");
  await db.posts.insert({ title });
}

Decode it:

  • "use server" at the top of the file marks every export as a server action.
  • The function runs only on the server, so it can touch the database directly.
  • It receives a FormData object, the standard web API for form contents.

Wiring it to a form

// app/new-post/page.js
import { createPost } from "../actions";

export default function NewPostPage() {
  return (
    <form action={createPost}>
      <input name="title" />
      <button type="submit">Publish</button>
    </form>
  );
}
  • Instead of action="/some/url", the form's action is the function itself. Next.js generates the network plumbing.
  • The name="title" attribute is what formData.get("title") reads. Names are the contract.
  • Notice there is no onSubmit, no e.preventDefault(), no fetch. The page can even stay a server component.
form(browser)server action"use server"databaseFormDatainsertrevalidatePath → fresh page
The mutation loop: the form posts FormData to the server action, the action writes to the database, and revalidation refreshes the cached page.

Quiz

In the form above, where does the createPost function execute when the user clicks Publish?

Quiz

The input is renamed to <input name="headline" /> but the action still calls formData.get("title"). What does it get?