« The Interactivity API is a new WordPress standard, native system that facilitates building interactive blocks. » Cette phrase de la documentation officielle de WordPress résume l’ambition de cette API stabilisée depuis WordPress 6.5 : permettre des interactions front-end sans écrire de JavaScript impératif, en s’appuyant sur des directives HTML et un état réactif partagé entre le serveur et le navigateur.
Sur le site de l’office de tourisme de la vallée d’Ossaline, le sélecteur de langue devait remplir un contrat précis : changer la langue affichée sans rechargement de page, tout en gardant le contenu déjà chargé visible pendant la transition. Voici comment ce sélecteur a été construit, pas à pas, avec les directives de l’Interactivity API.
Poser la structure du bloc et son état
Un bloc construit avec l’Interactivity API repose sur trois fichiers principaux : le rendu PHP côté serveur, un fichier view.js qui définit la logique réactive, et une configuration d’état initiale exposée via wp_interactivity_state(). Pour le sélecteur de langue, l’état initial contient la langue courante et la liste des langues disponibles sur la page, calculées côté serveur avant l’envoi du HTML.
wp_interactivity_state( 'osiv/language-switcher', array(
'currentLang' => pll_current_language(),
'availableLangs' => pll_languages_list(),
) );
Écrire les directives dans le rendu du bloc

Le rendu PHP du bloc attache le contexte réactif à un conteneur, puis chaque lien de langue reçoit une directive data-wp-on--click qui déclenche une action définie côté client, sans écouteur d’événement manuel :
<ul data-wp-interactive="osiv/language-switcher"
data-wp-context='{ "lang": "fr" }'>
<li data-wp-on--click="actions.switchLanguage"
data-wp-bind--aria-current="state.isCurrent">
Français
</li>
</ul>
La directive data-wp-bind--aria-current met à jour l’attribut d’accessibilité en fonction de l’état réactif, ce qui évite d’écrire une seule ligne de JavaScript pour ce comportement précis.
Définir l’action côté client
Le fichier view.js déclare l’action appelée par la directive, en s’appuyant sur getContext() pour lire la langue cliquée et sur une requête vers l’API REST de contenu traduit pour récupérer le nouveau contenu sans recharger la page :
import { store, getContext } from '@wordpress/interactivity';
store( 'osiv/language-switcher', {
actions: {
*switchLanguage() {
const context = getContext();
const response = yield fetch( `/wp-json/osiv/v1/page?lang=${ context.lang }` );
const data = yield response.json();
const state = document.querySelector( '[data-wp-interactive]' );
state.dispatchEvent( new CustomEvent( 'osiv-content-updated', { detail: data } ) );
},
},
} );
Le générateur permet d’utiliser yield pour attendre la réponse de façon lisible, un des apports notables de l’Interactivity API par rapport à un simple gestionnaire d’événement classique.
Gérer la transition visuelle
Pendant le temps de la requête, un indicateur de chargement s’affiche via une directive data-wp-class--is-loading liée à une propriété d’état booléenne. Cette approche évite l’écran blanc caractéristique d’un rechargement complet, tout en donnant un retour visuel immédiat au visiteur qui vient de cliquer.
- Un état initial calculé côté serveur, jamais deviné côté client
- Des directives pour chaque interaction, sans écouteur d’événement manuel
- Un indicateur de chargement pendant la requête de contenu traduit
Variante pour un site à fort trafic touristique
Sur un site saisonnier avec des pics de fréquentation en haute saison, la requête REST déclenchée à chaque changement de langue peut être mise en cache côté serveur avec un en-tête Cache-Control adapté à la durée de vie du contenu traduit, qui change rarement plus d’une fois par semaine sur ce type de site.
En résumé
L’Interactivity API permet de construire un sélecteur de langue réactif sans écrire de logique JavaScript impérative complexe, à condition de bien séparer l’état initial calculé côté serveur, les directives déclaratives dans le HTML, et les actions réactives dans le fichier client. Le résultat, un changement de langue sans rechargement de page, se construit avec moins de code qu’une solution en JavaScript classique équivalente.