đ CrĂ©ation dâune Server Action pour gĂ©rer un formulaire dans Next.js 13+
Les Server Actions permettent dâenvoyer directement des donnĂ©es Ă un serveur sans API Route, ce qui simplifie la gestion des formulaires.
1ïžâŁ Objectif : Formulaire de contact avec Server Actions
Nous allons créer un formulaire de contact qui envoie les données à une Server Action et affiche un message de confirmation.
â Ce que nous allons faire :
- Un formulaire en React (
app/contact/page.tsx
). - Une Server Action (
app/actions/contact.ts
). - Afficher un message de confirmation aprĂšs soumission.
2ïžâŁ CrĂ©ation de la Server Action
app/actions/contact.ts
"use server";
export async function sendMessage(formData: FormData) {
const name = formData.get("name") as string;
const email = formData.get("email") as string;
const message = formData.get("message") as string;
// VĂ©rification des champs
if (!name || !email || !message) {
return { error: "Tous les champs sont requis." };
}
// Simuler l'envoi à une base de données ou un service (ex: email)
console.log("Message reçu :", { name, email, message });
return { success: "Votre message a bien été envoyé !" };
}
â Explication :
- On définit la fonction
sendMessage
avec"use server"
pour quâelle sâexĂ©cute cĂŽtĂ© serveur. - On rĂ©cupĂšre les donnĂ©es du formulaire via
formData.get()
. - On effectue une validation basique.
- On affiche une rĂ©ponse de succĂšs ou dâerreur.
3ïžâŁ CrĂ©ation du formulaire avec appel Ă la Server Action
app/contact/page.tsx
"use client";
import { useState } from "react";
import { sendMessage } from "@/app/actions/contact";
export default function ContactPage() {
const [status, setStatus] = useState<string | null>(null);
async function handleSubmit(formData: FormData) {
const result = await sendMessage(formData);
if (result?.error) {
setStatus(result.error);
} else {
setStatus(result.success);
}
}
return (
<div className="max-w-md mx-auto p-4 border rounded-lg shadow-lg">
<h1 className="text-xl font-bold mb-4">Contactez-nous</h1>
<form action={handleSubmit} className="space-y-3">
<input
type="text"
name="name"
placeholder="Votre nom"
className="w-full p-2 border rounded"
required
/>
<input
type="email"
name="email"
placeholder="Votre email"
className="w-full p-2 border rounded"
required
/>
<textarea
name="message"
placeholder="Votre message"
className="w-full p-2 border rounded"
rows={4}
required
></textarea>
<button type="submit" className="w-full bg-blue-500 text-white py-2 rounded">
Envoyer
</button>
</form>
{status && <p className="mt-3 text-center">{status}</p>}
</div>
);
}
â Explication :
- Le formulaire est cÎté client (
"use client"
). - La Server Action
sendMessage
est appelée directement danshandleSubmit
. - On affiche un message de confirmation aprĂšs lâenvoi.
4ïžâŁ Test et Validation
- đ DĂ©marrer le projet :
npm run dev
- đ Aller sur
http://localhost:3000/contact
. - â Remplir le formulaire et envoyer un message.
- đŻ VĂ©rifier la console serveur pour voir les donnĂ©es envoyĂ©es.
5ïžâŁ Aller plus loin : Stocker les messages en base de donnĂ©es
Si on utilise Prisma avec une base de données SQLite ou PostgreSQL :
app/actions/contact.ts (avec Prisma)
"use server";
import { db } from "@/lib/db"; // Connexion Ă la base
export async function sendMessage(formData: FormData) {
const name = formData.get("name") as string;
const email = formData.get("email") as string;
const message = formData.get("message") as string;
if (!name || !email || !message) {
return { error: "Tous les champs sont requis." };
}
await db.message.create({
data: { name, email, content: message },
});
return { success: "Message enregistré en base de données !" };
}
â Effet : Le message est enregistrĂ© en base de donnĂ©es.
6ïžâŁ Comparaison avec une API Route
đč MĂ©thode | Server Action ("use server" ) | API Route (app/api/contact/route.ts ) |
---|---|---|
đïž ComplexitĂ© | Plus simple (directement dans le composant) | NĂ©cessite une route sĂ©parĂ©e |
⥠Performance | Moins dâallers-retours rĂ©seau | Requiert un fetch() |
đ SĂ©curitĂ© | Non exposĂ© cĂŽtĂ© client | Peut ĂȘtre accĂ©dĂ© via fetch() |
đ ExĂ©cution | Directe via form action={} | Via fetch() dans un useEffect ou onSubmit |
đŻ Conclusion : Pourquoi utiliser les Server Actions ?
đ„ Avantages :
- Code plus simple et lisible.
- Pas de
fetch()
, appel direct à la fonction serveur. - Sécurisé (aucune API exposée).
- Performance optimisĂ©e (moins de requĂȘtes rĂ©seau).
mis Ă jour le