WhoBuilt

Using Forms in Next.js

Sep 25, 2023· 10 min· 212K views·Watch on YouTube

Speaker

Lee, a software engineer at Vercel, explains how to build forms with Server Actions and revalidate data in the Next.js App Router.

From API routes to Server Actions

Lee contrasts Pages Router forms, which use an onSubmit handler and a separate API route, with App Router forms. The example is a todo list where users can add and delete items, with loading and error states.

Create todos and revalidate data

The page is an asynchronous Server Component that fetches todos, in this example from Vercel Postgres. A form’s action calls a server-side createTodo function, which validates input with Zod, inserts the todo, and calls revalidatePath so the page can show updated data.

Show pending states and delete items

A submit button uses React’s useFormStatus hook to show when a form is pending. Delete forms can be rendered for each todo and pass its ID in hidden form data. Lee notes that a Server Action can update cached data and return new UI in one network round trip.

Support accessibility and errors

The example labels inputs for screen readers and uses a polite live area to announce successful or failed actions. Lee demonstrates an error message after a two-second delay and explains why the button uses aria-disabled instead of disabled in this example.

Revalidate more selectively

For finer control than revalidating an entire path, Lee describes using revalidateTag with tagged data. He also mentions upcoming support for tagging data accessed through cache(), and names cookies, headers, optimistic UI, and redirects as other Server Action use cases.

Takeaways

  • Use a Server Action as a form action to handle mutations without creating a separate API route.
  • Validate submitted form data on the server before writing it to a database.
  • Call revalidatePath after a mutation so the page can refresh its cached data.
  • Use pending state and screen reader announcements to make form feedback clearer.
  • Use revalidateTag when you need to refresh specific tagged data instead of a whole path.

Mentioned in this talk

Search inside this talk

What was claimed 8

Related talks