vendredi 25 septembre 2026

À propos

Contact

Extensions

Une page d’administration en React avec @wordpress/components

Pourquoi réécrire des boutons, des champs et des notices en CSS maison quand la bibliothèque de composants de Gutenberg les fournit déjà, gratuitement et déjà accessibles ?

Par Clément Hadrot • 15 avril 2022 • 4 min de lecture • Aucun commentaire
Une page d'administration en React avec @wordpress/components

Pour une extension de gestion d’abonnements destinée à une salle d’escalade, l’écran de réglages initial en PHP classique (Settings API, champs générés à la main) commençait à montrer ses limites : validation en temps réel impossible sans rechargement de page, retours visuels peu clairs. Plutôt que d’écrire une interface React entièrement sur mesure avec ses propres styles, j’ai choisi de m’appuyer sur @wordpress/components, la même bibliothèque qui alimente l’éditeur de blocs.

Mettre en place l’outillage avec @wordpress/scripts

Plutôt que de configurer manuellement Webpack et Babel, le paquet @wordpress/scripts fournit une configuration prête à l’emploi, identique à celle utilisée par le cœur de WordPress pour ses propres blocs.

npm install --save-dev @wordpress/scripts
npm install @wordpress/components @wordpress/element @wordpress/api-fetch @wordpress/i18n
{
  "scripts": {
    "start": "wp-scripts start",
    "build": "wp-scripts build"
  }
}

Ce choix évite de maintenir soi-même une configuration de build, un gain de temps réel sur la durée du projet : chaque montée de version de WordPress met à jour cette configuration en même temps que le reste de l’écosystème des blocs, sans intervention nécessaire côté extension.

Monter l’application React dans l’admin

// admin.php
function escalade_afficher_page_reglages() {
    echo '<div id="escalade-reglages-app"></div>';
}

function escalade_charger_script_admin( $hook ) {
    if ( 'toplevel_page_escalade-reglages' !== $hook ) {
        return;
    }
    wp_enqueue_script(
        'escalade-admin-app',
        plugins_url( 'build/index.js', __FILE__ ),
        array( 'wp-element', 'wp-components', 'wp-api-fetch', 'wp-i18n' ),
        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' ),
        true
    );
    wp_enqueue_style( 'wp-components' );
}
add_action( 'admin_enqueue_scripts', 'escalade_charger_script_admin' );
L'essentiel à retenir : @wordpress/scripts fournit une configuration webpack prête à l'emploi ; apiFetch gère automatiquement le nonce REST, contrairement à fetch brut ; Les composants de Gutenberg partagent la même feuille de styles que l'admin natif

Enregistrer wp-components comme dépendance de style, plutôt que d’écrire une feuille de styles personnalisée, garantit que chaque bouton, champ et notice affiché reprend exactement l’apparence des écrans natifs de l’admin, y compris en cas de changement futur de thème d’administration.

Construire l’interface avec les composants existants

import { render, useState } from '@wordpress/element';
import { Panel, PanelBody, ToggleControl, TextControl, Button, Notice } from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';
import { __ } from '@wordpress/i18n';

function ReglagesApp() {
    const [ dureeGrace, setDureeGrace ] = useState( 7 );
    const [ rappelActif, setRappelActif ] = useState( true );
    const [ message, setMessage ] = useState( null );

    const enregistrer = () => {
        apiFetch( {
            path: '/escalade/v1/reglages',
            method: 'POST',
            data: { duree_grace: dureeGrace, rappel_actif: rappelActif },
        } ).then( () => {
            setMessage( __( 'Réglages enregistrés.', 'escalade-abonnements' ) );
        } );
    };

    return (
        <Panel>
            <PanelBody title={ __( 'Abonnements', 'escalade-abonnements' ) }>
                { message && <Notice status="success" isDismissible={ false }>{ message }</Notice> }
                <TextControl
                    label={ __( 'Délai de grâce (jours)', 'escalade-abonnements' ) }
                    type="number"
                    value={ dureeGrace }
                    onChange={ ( valeur ) => setDureeGrace( Number( valeur ) ) }
                />
                <ToggleControl
                    label={ __( 'Envoyer un rappel avant échéance', 'escalade-abonnements' ) }
                    checked={ rappelActif }
                    onChange={ setRappelActif }
                />
                <Button variant="primary" onClick={ enregistrer }>
                    { __( 'Enregistrer', 'escalade-abonnements' ) }
                </Button>
            </PanelBody>
        </Panel>
    );
}

render( <ReglagesApp />, document.getElementById( 'escalade-reglages-app' ) );

Aucun de ces composants (Panel, ToggleControl, TextControl, Button, Notice) n’a nécessité une seule ligne de CSS supplémentaire : leur apparence, leurs états de focus et leur comportement accessible sont hérités directement de la bibliothèque, la même qui équipe l’éditeur de blocs natif.

apiFetch plutôt que fetch brut

Utiliser fetch() natif face à un endpoint REST de WordPress impose de gérer soi-même l’en-tête X-WP-Nonce, sous peine d’une erreur 403 dès que la session change. apiFetch, fourni par @wordpress/api-fetch, s’en charge automatiquement lorsqu’il est chargé dans le contexte de l’admin, via une configuration injectée par WordPress lui-même.

  • Le nonce est automatiquement récupéré depuis wp-api-fetch localisé côté PHP, sans code additionnel dans l’extension
  • Les erreurs REST (objets WP_Error traduits en JSON) remontent sous forme de rejet de promesse, exploitable avec .catch()
  • Un middleware personnalisé peut être ajouté avec apiFetch.use() pour, par exemple, injecter un en-tête additionnel propre à l’extension

En résumé

S’appuyer sur @wordpress/components pour un écran d’administration réduit considérablement le travail de conception visuelle et garantit une cohérence immédiate avec le reste de l’admin WordPress. Ce choix impose en contrepartie de suivre les évolutions de cette bibliothèque au fil des versions de WordPress, un compromis largement acceptable pour ce projet au vu du temps gagné sur le design de l’interface elle-même.

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