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
FormDataobject, 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'sactionis the function itself. Next.js generates the network plumbing. - The
name="title"attribute is whatformData.get("title")reads. Names are the contract. - Notice there is no
onSubmit, noe.preventDefault(), nofetch. The page can even stay a server component.
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?