Un client gérant un blog à forte communauté m’a demandé de reproduire, sur son nouveau front Next.js, l’expérience de commentaires qu’il avait sous son thème WordPress classique : fils de discussion imbriqués, formulaire de réponse, modération automatique des liens suspects. L’API REST expose bien les commentaires, mais sans reconstruire elle-même la hiérarchie ni la logique anti-spam habituellement gérée par le thème et par Akismet côté rendu serveur.
Cet article couvre la récupération des commentaires, leur affichage sous forme d’arbre, la publication en tant que visiteur anonyme ou utilisateur connecté, et les limites de la modération côté headless — sans aborder les formulaires de contact génériques, qui relèvent d’un besoin différent.
Récupérer les commentaires d’un article
La route /wp-json/wp/v2/comments accepte un paramètre post pour filtrer sur un article précis, et renvoie une liste plate triée par défaut du plus ancien au plus récent :
GET /wp-json/wp/v2/comments?post=42&_fields=id,parent,author_name,content.rendered,date
Chaque commentaire porte un champ parent qui vaut 0 pour un commentaire de premier niveau, ou l’identifiant du commentaire auquel il répond. Comme pour les menus, c’est au front de reconstruire l’arbre avant l’affichage :
function construireArbreCommentaires(commentaires, parentId = 0) {
return commentaires
.filter((c) => c.parent === parentId)
.map((c) => ({
...c,
reponses: construireArbreCommentaires(commentaires, c.id),
}));
}
WordPress limite par défaut la profondeur d’imbrication à cinq niveaux dans l’administration (réglage « Commentaires imbriqués sur X niveaux »), une limite purement visuelle côté thème classique qui n’est pas appliquée par l’API REST elle-même : côté front, il faut donc décider soi-même jusqu’à quelle profondeur afficher les réponses, ou aplatir visuellement au-delà d’un certain niveau.
Poster un commentaire en visiteur anonyme
La création d’un commentaire se fait en POST vers la même route, sans authentification si les réglages de discussion de WordPress l’autorisent :

const reponse = await fetch('https://exemple.fr/wp-json/wp/v2/comments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
post: 42,
parent: 0,
author_name: 'Camille Durand',
author_email: 'camille@exemple.fr',
content: 'Merci pour cet article, très clair !',
}),
});
if (!reponse.ok) {
const erreur = await reponse.json();
throw new Error(erreur.message);
}
Le statut du commentaire créé dépend directement des réglages de WordPress (Réglages → Discussion) : si « Un commentaire doit être approuvé manuellement » est coché, le commentaire est créé avec le statut hold (en attente) et n’apparaît pas immédiatement dans la liste publique, ce qu’il faut expliquer clairement à l’utilisateur côté front pour éviter qu’il pense son commentaire perdu.
Poster en tant qu’utilisateur connecté
Pour un utilisateur authentifié (via jeton JWT ou cookie de session selon le mécanisme choisi), il suffit de transmettre l’en-tête d’authentification correspondant ; WordPress associe alors automatiquement le commentaire au compte utilisateur, sans avoir à renseigner author_name et author_email manuellement :
await fetch('https://exemple.fr/wp-json/wp/v2/comments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jeton}`,
},
body: JSON.stringify({ post: 42, parent: 0, content: 'Bien vu !' }),
});
Un utilisateur avec la capacité moderate_comments verra son commentaire approuvé instantanément, contrairement à un visiteur anonyme soumis aux réglages de modération.
Modération et anti-spam : ce qui ne suit pas automatiquement
Sur un thème WordPress classique, Akismet s’intègre au flux de soumission de commentaire via les hooks natifs (comment_post, entre autres) et fonctionne de façon transparente, y compris pour les commentaires créés via l’API REST : Akismet reste actif tant qu’il est installé, indépendamment du point d’entrée utilisé pour créer le commentaire. En revanche, certaines protections visuelles habituelles (case à cocher, délai anti-robot côté formulaire) doivent être réimplémentées côté front, puisqu’elles ne font pas partie de l’API elle-même.
- Un délai minimal entre l’affichage du formulaire et la soumission, pour filtrer les robots trop rapides.
- Un champ honeypot invisible, à vérifier côté front avant même d’appeler l’API, en complément d’Akismet.
- Un message clair distinguant un commentaire en attente de modération d’un commentaire rejeté, pour ne pas laisser l’utilisateur dans l’incertitude.
Vérifier le statut d’un commentaire après soumission
La réponse renvoyée à la création d’un commentaire contient un champ status uniquement visible pour un utilisateur autorisé à modérer ; pour un visiteur anonyme, la réponse REST filtre ce champ. Le front doit donc se baser sur le code HTTP 201 (créé) plutôt que sur le contenu du champ status pour confirmer la soumission, puis afficher un message générique adapté au cas où le commentaire ne serait pas immédiatement visible dans la liste.
Un formulaire de commentaire headless qui ne prévoit pas l’état « en attente de modération » finit toujours par recevoir un signalement d’utilisateur pensant que son message a disparu : ce cas doit être traité dès la première version du composant, pas ajouté après coup.
En résumé
Afficher des commentaires en headless demande de reconstruire soi-même la hiérarchie parent/enfant, absente de la réponse brute de l’API. Poster un commentaire fonctionne de façon similaire en anonyme et en connecté, avec une différence de statut selon les réglages de modération. Akismet continue de filtrer les commentaires créés via l’API, mais les protections visuelles du formulaire doivent être réimplémentées côté front.