Day 15 β Server Actions I: Forms without APIs
π§ Day 15 β Server Actions I: Forms without APIs
Zero to Hero β Hands-on Next.js Tutorial
Welcome to Week 3! We focused on Getting Data last week. Now we focus on Changing Data (Mutations).
Historically, submitting a form meant:
- Create
api/submit/route.ts. - Create a Client Component form.
onSubmit, prevent default.fetch('/api/submit', { method: 'POST' ... }).- Handle loading, error, success state.
Server Actions kill this boilerplate. You can just call a function.
π¦ 1. What is a Server Action?
It is an asynchronous function that runs on the server, but can be invoked from the Client or Server.
You mark it with the 'use server' directive.
// src/actions.ts
'use server';
export async function createPost(formData: FormData) {
const title = formData.get('title');
await db.post.create({ data: { title } });
console.log("Post created!");
}
π© 2. Using it in a Form
You can pass this function directly to the action prop of a form. No onSubmit handler needed!
// src/app/page.tsx
import { createPost } from '@/actions';
export default function Page() {
return (
<form action={createPost}>
<input name="title" type="text" className="border p-2" />
<button type="submit">Create Post</button>
</form>
);
}
What happens?
- User clicks submit.
- Next.js makes a POST request to the same URL.
- The
createPostfunction runs on the server. - The page refreshes automatically!
π§ 3. Progressive Enhancement
Because this is a standard HTML <form>, it works without JavaScript.
If the userβs JS hasnβt loaded yet, or if they have JS disabled, the form still works.
Try doing that with axios and useState!
π₯ 4. Revalidation
After we create a post, we want the list of posts to update. We donβt need to manually refetch. We just tell Next.js to purge the cache.
'use server';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
export async function createPost(formData: FormData) {
await db.post.create({ ... });
// 1. Purge the cache for the home page
revalidatePath('/');
// 2. Redirect the user
redirect('/dashboard');
}
π§ͺ Challenge: Day 15
- Create a file
actions.ts. - Export a function
logMessagethat takesFormData, gets a βmsgβ field, and logs it to the server console. - Create a form in
page.tsx. - Import
logMessageand assign it to<form action={...}>. - Submit the form. Check your terminal (not browser console). You should see the log!
See you tomorrow for Server Actions Part II: Loading & Error States! β³