Illustration for the post3 façons de gérer les formulaires dans Next.js

3 façons de gérer les formulaires dans Next.js

Lorsque l’on développe des applications web avec des formulaires dans Next.js, plusieurs techniques sont disponibles.

Elles permettent toutes de gérer l’envoi des données côté client et leur traitement côté serveur. Alors comment choisir ?

Découvrons trois approches pour implémenter un formulaire dans Next.js :

Traiter un formulaire avec le comportement par défaut du navigateur

Pas besoin de JavaScript pour traiter un formulaire ! Les navigateurs fournissent déjà tout ce qu’il faut pour remplir et envoyer des données.

Vous pouvez créer un formulaire HTML standard avec un attribut action pointant vers une route côté serveur :

<form action="/handle-form">
  <label for="firstname">Votre prénom</label>
  <input type="text" name="firstname" id="firstname" />
  <button type="submit">Envoyer</button>
</form>

Lorsque le formulaire est soumis, le navigateur envoie une requête GET vers l’URL de l’action, contenant les données du formulaire.

On peut utiliser l’attribut method="POST" pour utiliser plutôt une requête POST, ce qui est préférable dès que le formulaire déclenche une action non triviale.

Pour implémenter /handle-form, vous pouvez utiliser un route handler, c’est-à-dire un point d’entrée d’API dans le langage de Next.js.

Vous n’êtes peut-être pas encore familier des route handlers, voici donc un exemple commenté :

// Fichier: app/handle-form/route.ts
// Le nom du dossier donnera l'URL du point d'entrée d'API, 
// ici ce sera donc "/handle-form"

// NextRequest et NextResponse sont des utilitaires
// pour gérer facilement les requêtes et réponses HTTP
import { NextRequest, NextResponse } from "next/server";

// Le formulaire déclenche une requête GET,
// donc on doit exporter une fonction appellée GET
export async function GET(req: NextRequest) {
    // req.nextUrl est un champ fourni par Next.js
    // pour nous faciliter la vie.
    // On peut notamment y trouver les paramètres d'URL, 
    // et donc le contenu du formulaire
    console.log("Prénom:", req.nextUrl.searchParams.get("firstname"))
    
    // On construit l'URL absolue de redirection,
    // à partir de l'URL de la requête
    const successUrl = new URL('/success', req.url);
    return NextResponse.redirect(successUrl);
}

Comme on n’utilise pas de JavaScript côté client, il faut trouver un moyen d’afficher un message de succès une fois le formulaire traité.

C’est pourquoi la dernière étape du route handler consiste à rediriger l’utilisateur vers une page de succès.

Cela peut paraître complexe : les server actions que l’on va présenter dans la suite de cet article vont justement nous faciliter la vie ! Mais d’abord décrivons l’approche “Single Page Application” à base de JavaScript.

Traiter un formulaire avec du JavaScript côté client

Un autre modèle courant typique des SPA consiste à gérer la soumission des formulaires à l’aide de JavaScript côté client.

On utilise typiquement une callback onSubmit fournie par React, qui nous permet d’intercepter la soumission du formulaire pour la gérer nous-mêmes.

<form onSubmit={(evt) => { 
    evt.preventDefault()
    const firstname = evt.currentTarget.elements.firstname
    const res = await fetch(
		`/handle-form?firstname=?{encodeURIComponent(firstname)}`
		)
  }>
  <!-- champs du formulaire -->
</form>

La documentation Mozilla décrit bien les champs disponibles dans evt.currentTarget pour un élément <form>.

Une API de traitement de formulaires utilise généralement le format JSON, dans une logique REST. Il faut donc adapter notre route handler pour renvoyer une donnée JSON, au lieu de déclencher une redirection :

   return NextResponse.json({
     success: true, 
     message: "Formulaire bien reçu !"
   })

Côté client, avoir le contrôle sur l’envoi du formulaire facilite la gestion de l’expérience utilisateur : valider les données en temps réel, afficher une interface de chargement, des messages d’erreur et de succès, le tout sans avoir recharger entièrement la page.

Mais le traitement côté backend reste complexe, il faut manipuler des requêtes HTTP, et le formulaire ne fonctionne plus si JavaScript est désactivé.

Découvrons donc l’alternative la plus moderne, avec les actions serveur.

Traiter un formulaire avec les Server Actions de Next.js.

Les Server Actions permettent d’implémenter des traitements côté serveur, sans avoir à créer un point d’entrée d’API. Elles sont notamment optimisées pour gérer des formulaires.

En résumé, au lieu de gérer des requêtes et des réponses HTTP via un route handler, on se contente d’écrire une fonction. Next.js gère tout le reste !

Voici un exemple d’action serveur :

"use server"
function handleForm(formData) {
  console.log("Prénom:", formData.get("firstname"))
  return {
     success: true, 
     message: "Formulaire bien reçu !"
   }
}

On peut ensuite l’utiliser comme une action du formulaire :

<form action={handleForm}>
  <!-- champs du formulaire -->
</form>

Le code est beaucoup plus simple !

La directive "use server" déclenche toute la magie de Next.js. Elle indique que la fonction handleForm doit être exécutée sur le serveur lorsque le formulaire est soumis.

Pour gérer l’état du formulaire, la syntaxe se complique tout de même un peu. Il faut utiliser de nouveaux hooks React tels que useActionState. Nous aurons l’occasion d’y revenir dans un prochain article !

Choisir la bonne approche pour votre application Next.js

Cela fonctionne exactement de la même manière avec le framework Astro.js, qui fournit aussi ces trois approches et des actions serveur.

Dans tous les cas, n’oubliez pas qu’il n’y a pas de mauvaise réponse, la meilleure approche pour gérer des formulaires en React et Next.js dépendra toujours de vos contraintes techniques et organisationnelles !

Vous avez apprécié cette ressource ?

Découvrez toutes nos formations Next.js et Astro en présentiel ou en distanciel

Voire toutes les ressources

Partager sur Bluesky Partager sur X
Flux RSS