vendredi 25 septembre 2026

À propos

Contact

Headless & API

Le rendu des blocs de groupe theme.json perdu dans l’export headless React

Les couleurs et espacements définis dans theme.json pour un bloc Group disparaissent en headless. Voici comment les récupérer via le endpoint global-styles.

Par Clément Hadrot • 2 février 2024 • 5 min de lecture • Aucun commentaire
Le rendu des blocs de groupe theme.json perdu dans l'export headless React

« Le site affiche bien le texte, mais tout est en noir sur blanc alors que la maquette prévoyait un fond bleu ciel pour les sections mises en avant ». C’est le retour d’un designer sur la première version headless d’un site vitrine pour une école de commerce, construit sur WordPress avec l’éditeur de site et un thème basé sur theme.json, puis consommé par un front React.

Le problème ne venait pas d’un oubli de développement au sens strict : le bloc Group utilisé sur la page, avec son réglage de couleur de fond « Accent » défini dans le thème, s’affichait parfaitement dans l’éditeur WordPress et sur un site classique avec ce même thème. Mais dès qu’on quittait le rendu PHP natif de WordPress pour reconstruire la page dans un composant React, la couleur disparaissait purement et simplement.

Pourquoi l’API REST ne suffit pas ici

L’endpoint /wp/v2/pages/{id}, interrogé avec le paramètre ?context=edit ou en view, renvoie le champ content.rendered, c’est-à-dire le HTML déjà généré par WordPress à partir des blocs Gutenberg. Ce HTML contient bien une classe comme has-accent-background-color sur la div du bloc Group. Jusque-là, tout va bien.

Le problème apparaît dès que le front React ne se contente pas d’injecter ce HTML tel quel (ce qui serait possible mais peu flexible pour un vrai composant piloté par des données), mais reconstruit sa propre structure de composants à partir des blocs bruts, récupérés en context=edit sous forme d’un tableau de blocs analysés. Dans ce cas, le développeur travaille avec les attributs du bloc (backgroundColor: "accent") et non plus avec la classe CSS finale. Or, la couleur réelle que représente le jeton accent n’existe nulle part dans la réponse de l’API contenu : elle est définie exclusivement dans theme.json, un fichier que l’API REST classique du contenu ignore totalement.

La solution : interroger le endpoint global-styles

WordPress expose depuis la version 5.9 un endpoint dédié aux styles globaux, accessible (selon la configuration et les droits) via /wp/v2/global-styles/{id} ou, plus utilement pour un usage headless en lecture, en résolvant les réglages du thème actif directement depuis son fichier theme.json exposé publiquement par un endpoint personnalisé.

L'essentiel à retenir : L'API REST du contenu ne renvoie que le HTML brut du bloc, pas les styles globaux qui l'habillent ; Le endpoint global-styles expose les réglages theme.json sous forme de JSON exploitable ; Un mappage manuel entre classes de bloc et jetons de style reste nécessaire côté React

Sur ce projet, la solution a consisté à créer un petit endpoint REST dédié, qui expose uniquement la palette de couleurs et les espacements définis dans theme.json, sans exposer l’intégralité de la configuration du thème :

add_action('rest_api_init', function () {
    register_rest_route('projet/v1', '/design-tokens', [
        'methods'  => 'GET',
        'callback' => function () {
            $theme_json = WP_Theme_JSON_Resolver::get_merged_data();
            $settings = $theme_json->get_settings();
            return [
                'couleurs' => $settings['color']['palette']['theme'] ?? [],
                'espacements' => $settings['spacing']['spacingSizes']['theme'] ?? [],
            ];
        },
        'permission_callback' => '__return_true',
    ]);
});

Côté React, ce endpoint est appelé une seule fois au build (ou en cache long côté front), et sert à construire une table de correspondance entre le slug de couleur (accent) et sa valeur hexadécimale réelle, elle-même transformée en variable CSS ou en jeton Tailwind selon la stack du projet.

Mapper les classes plutôt que les attributs bruts

Une alternative, finalement écartée sur ce projet mais plus simple à mettre en œuvre rapidement, consiste à ne pas reconstruire les blocs depuis leurs attributs bruts mais à conserver le HTML rendu par WordPress (content.rendered) et à s’assurer que les classes générées par Gutenberg (has-accent-background-color, has-large-font-size) sont bien reprises dans une feuille de styles React générée à partir des mêmes jetons theme.json, via le endpoint ci-dessus.

Ce que ça implique pour l’équipe design

  • Toute modification de la palette dans theme.json doit être répercutée dans le front React, ce qui impose soit un rebuild du site à chaque changement de thème, soit un appel dynamique au endpoint de jetons à chaque rendu.
  • Les designers doivent être informés que renommer un jeton de couleur dans l’éditeur de site (« Accent » devient « Principal ») casse silencieusement le mappage côté React tant que celui-ci n’est pas régénéré.
  • Un test automatisé comparant la liste des jetons exposés par l’API à la liste utilisée côté React permet de détecter un jeton manquant avant la mise en production.

Sur un site headless construit avec l’éditeur de site, theme.json n’est pas un détail d’implémentation du thème PHP : c’est une véritable source de vérité design qu’il faut exposer explicitement à son front, au même titre que le contenu.

En résumé

Le rendu natif de Gutenberg cache une dépendance forte entre le contenu des blocs et la configuration du thème, une dépendance que l’API REST classique ne restitue pas. Dès qu’un projet headless reconstruit ses propres composants à partir des attributs de blocs plutôt que du HTML déjà rendu, il doit prévoir un canal explicite pour récupérer les réglages de theme.json, sous peine de voir disparaître des styles pourtant bien définis et visibles dans l’éditeur WordPress.

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