Skip to Content
🎉 Utilisez JS efficacement →

🚀 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 dans handleSubmit.
  • On affiche un message de confirmation après l’envoi.

4️⃣ Test et Validation

  • 📌 Démarrer le projet :
  • 📝 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éthodeServer Action ("use server")API Route (app/api/contact/route.ts)
🏗️ ComplexitéPlus simple (directement dans le composant)Nécessite une route séparée
PerformanceMoins d’allers-retours réseauRequiert un fetch()
🔒 SécuritéNon exposé côté clientPeut être accédé via fetch()
🔄 ExécutionDirecte 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