Le WordPress d'aujourd'hui, décodé pour les développeurs

Headless & API

Un webhook de publication prévient un front headless du changement

Comment déclencher un webhook à la publication d'un article WordPress pour prévenir instantanément un front découplé, avec le code complet.

Par Clément Hadrot • 5 novembre 2024 • 4 min de lecture • Aucun commentaire
Un webhook de publication prévient un front headless du changement

Comment un front découplé sait-il qu’un article vient d’être publié, alors que WordPress et l’hébergement du site statique ou du serveur Node.js n’ont, par défaut, aucune conversation entre eux ? La réponse la plus simple reste un webhook : une requête HTTP sortante que WordPress envoie lui-même dès qu’un événement précis se produit, ici la publication ou la mise à jour d’un contenu.

Ce mécanisme évite au front de sonder en boucle l’API REST pour détecter un changement (une pratique coûteuse et peu réactive). À la place, c’est WordPress qui prévient activement le front, qui peut alors régénérer une page statique, invalider un cache, ou notifier un service tiers.

Choisir le bon hook : transition_post_status

Beaucoup de tutoriels s’appuient sur save_post, qui se déclenche à chaque enregistrement, y compris pour un brouillon automatique ou une simple modification de métadonnée. Pour ne réagir qu’aux changements de statut réellement significatifs, transition_post_status est plus précis : il fournit le nouveau statut, l’ancien statut, et l’objet article.

add_action( 'transition_post_status', function( $nouveau_statut, $ancien_statut, $post ) {
    if ( $post->post_type !== 'post' ) {
        return;
    }
    if ( $nouveau_statut !== 'publish' || $ancien_statut === 'publish' ) {
        return;
    }

    wp_remote_post( 'https://mon-front-headless.example.com/api/revalidate', array(
        'timeout'  => 5,
        'blocking' => false,
        'body'     => array(
            'post_id' => $post->ID,
            'slug'    => $post->post_name,
            'secret'  => defined( 'WEBHOOK_SECRET' ) ? WEBHOOK_SECRET : '',
        ),
    ) );
}, 10, 3 );

La condition sur les deux statuts garantit que le webhook ne se déclenche qu’au passage réel vers « publié », pas à chaque republication d’un article déjà en ligne. Pour couvrir aussi les mises à jour d’un contenu déjà publié, une seconde condition dédiée est nécessaire.

Ne jamais bloquer l’interface d’administration

Le paramètre 'blocking' => false passé à wp_remote_post() est déterminant : sans lui, WordPress attend la réponse HTTP du front avant de terminer l’enregistrement de l’article, ce qui peut geler l’écran de publication pendant plusieurs secondes si le service distant est lent ou indisponible. En mode non bloquant, la requête part en arrière-plan et l’administrateur du site retrouve immédiatement la main.

L'essentiel à retenir : Hook transition_post_status plutôt que save_post seul ; Requête HTTP asynchrone vers le front ; Gérer les échecs sans bloquer l'admin

Prévenir plusieurs mises à jour, pas seulement la publication

Un front headless a aussi besoin d’être informé lorsqu’un article déjà publié est corrigé. Le hook post_updated couvre ce cas, mais il se déclenche aussi pour des changements mineurs comme l’ajout d’un tag. Pour limiter le bruit, il est courant de comparer le contenu avant et après :

  • Comparer $post_before->post_modified_gmt avec le nouveau, pour éviter les doublons de webhook sur une même sauvegarde.
  • Ne déclencher le webhook que pour les statuts publish, en ignorant les brouillons et les révisions automatiques.
  • Ajouter un court délai (par exemple via une tâche planifiée avec wp_schedule_single_event()) si l’éditeur enregistre plusieurs fois de suite en quelques secondes, afin de regrouper les appels.

Sécuriser la réception côté front

Le webhook transporte une information sensible : il révèle qu’un contenu a changé, et potentiellement son identifiant. Sans protection, n’importe qui connaissant l’URL de revalidation pourrait déclencher des reconstructions à volonté, ce qui peut saturer les quotas d’un hébergeur facturé à la requête de build. La pratique courante consiste à transmettre un secret partagé, vérifié côté front avant d’accepter la requête :

if ( $_SERVER['HTTP_X_WEBHOOK_SECRET'] !== getenv( 'WEBHOOK_SECRET' ) ) {
    http_response_code( 401 );
    exit;
}

Ce contrôle, aussi simple soit-il, écarte l’essentiel des tentatives d’appel non autorisées.

Gérer l’échec du webhook

Un webhook non bloquant a un revers : WordPress n’attend pas la réponse et ignore donc les erreurs du service distant. Si le front est temporairement indisponible, la notification est perdue sans qu’aucune alerte ne remonte dans l’administration. Pour limiter ce risque, il est recommandé de journaliser chaque envoi via error_log() ou un outil de suivi dédié, et de prévoir un mécanisme de rattrapage manuel, comme un bouton dans l’administration qui redéclenche le webhook pour un article donné.

Pour aller plus loin

Le webhook déclenché par transition_post_status reste la solution la plus légère pour prévenir un front découplé d’un changement de contenu, sans dépendance externe ni file d’attente. Elle convient parfaitement à un site avec un rythme de publication modéré. Au-delà de quelques dizaines d’articles modifiés par heure, une file de messages ou un service de mise en cache intermédiaire devient préférable pour éviter de multiplier les reconstructions redondantes du front.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi