Un client tenait à son référencement, construit patiemment sur cinq ans avec un thème PHP classique bien structuré. Il voulait pourtant un configurateur de produit interactif digne d’une application moderne, avec des filtres en temps réel et une prévisualisation instantanée. Migrer tout le site en Next.js pour une seule fonctionnalité aurait été disproportionné, coûteux, et risqué pour le SEO existant.
La solution retenue tient en une phrase : garder WordPress et son thème PHP comme moteur de rendu principal, et ne découpler que les zones réellement interactives, sous forme de petites applications JavaScript autonomes montées à des endroits précis de la page.
Le principe : des zones interactives, pas un site entier
Le thème continue de générer le HTML avec get_header(), la boucle WordPress classique et get_footer(). À l’intérieur de ce gabarit, certains conteneurs vides servent de point d’ancrage à une application JS indépendante :
<div id="configurateur-produit" data-produit-id="<?php echo esc_attr( get_the_ID() ); ?>"></div>
Chaque conteneur porte les données minimales nécessaires au démarrage de l’application (identifiant produit, langue, devise) via des attributs data-*, générés côté PHP au moment du rendu de la page.
Ce que chaque îlot fait réellement
Une fois le DOM chargé, un petit script se charge de repérer les conteneurs présents sur la page et d’y monter l’application correspondante :
document.querySelectorAll('[id^="configurateur-"]').forEach((el) => {
montageConfigurateur(el, {
produitId: el.dataset.produitId,
});
});
L’application interroge ensuite l’API REST de WordPress (une route personnalisée sous un espace de noms dédié) pour récupérer les options, variantes et disponibilités du produit, et rend son interface exclusivement dans son conteneur, sans jamais toucher au reste de la page.

Ce qui reste dans le thème, ce qui part dans l’îlot
| Reste au thème PHP | Passe dans l’îlot JS |
|---|---|
| Titre, description, balisage SEO | Sélection des options du produit |
| Navigation, en-tête, pied de page | Prévisualisation en temps réel |
| Contenu éditorial, images statiques | Calcul de prix dynamique |
Pourquoi cette approche tient dans le temps
Chaque îlot reste petit et remplaçable indépendamment des autres : on peut réécrire le configurateur produit dans un autre framework sans toucher au reste du site, puisqu’il ne communique avec le thème que par ses attributs data-* initiaux et par l’API REST ensuite. Le couplage est volontairement faible.
- Le référencement reste porté par le rendu PHP, jamais dépendant d’un rendu JavaScript côté client.
- Le temps de développement reste proportionné au besoin réel, pas à une réécriture complète du site.
- Les équipes qui maîtrisent PHP et celles qui maîtrisent le JS moderne peuvent travailler sur des périmètres clairement séparés.
Communiquer entre deux îlots voisins
Un second cas s’est présenté un peu plus tard sur le même projet : un îlot de filtres devait influencer un îlot de résultats situé plus bas dans la page, sans qu’ils partagent le même arbre de composants. La solution la plus simple est restée un événement DOM personnalisé, émis par l’îlot source et écouté par l’îlot destination, sans introduire de bibliothèque de gestion d’état globale pour un besoin aussi ponctuel.
document.dispatchEvent(new CustomEvent('filtres:changes', { detail: filtresActifs }));
Cette approche reste volontairement rudimentaire : elle suffit tant que le nombre d’îlots qui doivent se parler reste faible, et elle évite d’importer tout un système de gestion d’état pour deux composants qui échangent occasionnellement quelques valeurs.
Les limites de l’exercice
Cette architecture ne convient pas à un site où la majorité des pages sont fortement interactives : à ce stade, multiplier les îlots revient à réinventer un front complet, en moins bien outillé. Elle convient parfaitement à un site à dominante éditoriale qui a besoin de quelques poches d’interactivité ciblées, ce qui couvre une grande partie des projets vitrines et e-commerce simples.
La question à se poser avant de découpler un site entier : combien de pages ont réellement besoin d’être une application, et combien ont juste besoin d’un peu d’interactivité localisée ?
En résumé
Le headless partiel évite le tout ou rien. Il permet de moderniser exactement les zones qui en ont besoin, sans sacrifier ni le SEO acquis avec le thème PHP existant, ni la vitesse de mise en œuvre. C’est souvent le compromis le plus raisonnable avant d’envisager un découplage complet du site.