Builders Academy
Next.js 15 — Applications Full-Stack Modernes
2 of 3

Chapitre 1 · Leçon 2

Server Actions

Mutations serveur directement depuis les composants

Section 1

Créer et utiliser des Server Actions

Step 1

Server Action basique

Une Server Action est une fonction asynchrone marquée 'use server'. Elle s'exécute sur le serveur mais peut être appelée depuis le client comme une fonction normale.

app/actions/tutorial.actions.ts

tsx
1"use server";
2
3import { revalidatePath } from "next/cache";
4import { redirect } from "next/navigation";
5import { z } from "zod";
6import { db } from "@/lib/db";
7
8const CreateTutorialSchema = z.object({
9  title: z.string().min(5).max(100),
10  description: z.string().min(20),
11  level: z.enum(["Beginner", "Intermediate", "Advanced"]),
12  categorySlug: z.string(),
13});
14
15export async function createTutorial(formData: FormData) {
16  // 1. Valider les données
17  const parsed = CreateTutorialSchema.safeParse({
18    title: formData.get("title"),
19    description: formData.get("description"),
20    level: formData.get("level"),
21    categorySlug: formData.get("categorySlug"),
22  });
23
24  if (!parsed.success) {
25    return { error: parsed.error.flatten().fieldErrors };
26  }
27
28  // 2. Écrire en DB
29  const tutorial = await db.tutorial.create({
30    data: {
31      ...parsed.data,
32      slug: slugify(parsed.data.title),
33    },
34  });
35
36  // 3. Invalider le cache Next.js
37  revalidatePath("/tutorials");
38
39  // 4. Rediriger
40  redirect(`/tutorials/${tutorial.slug}`);
41}

Step 2

Utiliser une Server Action dans un formulaire

Les formulaires HTML peuvent appeler une Server Action directement via l'attribut action. Ça fonctionne même sans JavaScript côté client.

app/actions/tutorial.actions.ts

tsx
1"use server";
2
3import { revalidatePath } from "next/cache";
4import { redirect } from "next/navigation";
5import { z } from "zod";
6import { db } from "@/lib/db";
7
8const CreateTutorialSchema = z.object({
9  title: z.string().min(5).max(100),
10  description: z.string().min(20),
11  level: z.enum(["Beginner", "Intermediate", "Advanced"]),
12  categorySlug: z.string(),
13});
14
15export async function createTutorial(formData: FormData) {
16  // 1. Valider les données
17  const parsed = CreateTutorialSchema.safeParse({
18    title: formData.get("title"),
19    description: formData.get("description"),
20    level: formData.get("level"),
21    categorySlug: formData.get("categorySlug"),
22  });
23
24  if (!parsed.success) {
25    return { error: parsed.error.flatten().fieldErrors };
26  }
27
28  // 2. Écrire en DB
29  const tutorial = await db.tutorial.create({
30    data: {
31      ...parsed.data,
32      slug: slugify(parsed.data.title),
33    },
34  });
35
36  // 3. Invalider le cache Next.js
37  revalidatePath("/tutorials");
38
39  // 4. Rediriger
40  redirect(`/tutorials/${tutorial.slug}`);
41}

Topics and skills covered

  • Next.js
  • Server Actions
  • Forms
  • Mutations