Un bloc « compteur de stock » affichait dynamiquement un message d’état côté client, sans rechargement de page, grâce à l’Interactivity API introduite avec WordPress 6.5 : « Plus que 3 en stock », « Rupture de stock », « Disponible ». Le contenu initial du bloc, rendu côté serveur, était bien traduit dans les trois langues du site. Mais dès qu’une interaction déclenchait une mise à jour de ce message côté client — par exemple après la sélection d’une variation de produit — le nouveau texte s’affichait systématiquement en français, quelle que soit la langue de la page consultée.
Ce comportement s’explique par une caractéristique propre à l’Interactivity API : une partie du texte affiché n’est jamais rendue côté serveur par PHP, donc jamais soumise aux mécanismes de traduction habituels de Polylang ou WPML, qui interviennent précisément à ce niveau. Comprendre cette limite est indispensable pour concevoir un bloc interactif réellement traduisible.
Pourquoi le texte généré côté client échappe à la traduction classique
L’Interactivity API permet à un bloc de mettre à jour son affichage directement dans le navigateur, via un état JavaScript réactif, sans recharger la page ni repasser par une requête PHP complète. Cette approche améliore nettement la réactivité perçue, mais elle implique que tout texte généré ou modifié à ce niveau — dans un fichier view.js du bloc — vit entièrement côté client, hors du cycle de rendu PHP où Polylang et WPML interceptent habituellement le contenu à traduire.
Concrètement, un texte codé en dur dans la logique JavaScript du bloc reste identique quelle que soit la langue de la page, exactement comme une chaîne de thème non internationalisée resterait figée dans une seule langue en PHP classique.

La solution : wp_set_script_translations
WordPress fournit une fonction dédiée à ce cas précis, disponible depuis plusieurs versions et pleinement compatible avec les blocs utilisant l’Interactivity API : wp_set_script_translations(), qui relie un script JavaScript enregistré à un domaine de traduction et à un répertoire de fichiers de traduction au format JSON, générés automatiquement à partir des fichiers .po classiques du projet.
// Dans le fichier PHP d'enregistrement du bloc
function mon_bloc_enregistrer_traductions() {
wp_set_script_translations(
'mon-bloc-view-script',
'mon-domaine-texte',
plugin_dir_path(__FILE__) . 'languages'
);
}
add_action('init', 'mon_bloc_enregistrer_traductions');
Côté JavaScript, le texte doit être entouré des fonctions de traduction fournies par le module @wordpress/i18n, l’équivalent JavaScript des fonctions PHP __() et _e() :
import { __ } from '@wordpress/i18n';
const messageStock = stock > 0
? __('Plus que %d en stock', 'mon-domaine-texte').replace('%d', stock)
: __('Rupture de stock', 'mon-domaine-texte');
Générer les fichiers de traduction nécessaires
Cette mécanique suppose l’existence de fichiers JSON de traduction, générés à partir des fichiers .po traditionnels via l’outil en ligne de commande WP-CLI, spécifiquement la commande dédiée à l’export des traductions JavaScript :
wp i18n make-json languages/ --no-purge
Cette commande produit, pour chaque fichier .po présent, un ou plusieurs fichiers JSON nommés selon une convention précise incluant un hachage du chemin du script concerné, que WordPress sait retrouver automatiquement grâce à l’appel de wp_set_script_translations().
Et pour un site utilisant Polylang ou WPML plutôt que des fichiers .po classiques ?
Cette mécanique de traduction JavaScript reste indépendante de Polylang et WPML : elle repose sur le système d’internationalisation natif de WordPress, pas sur les tables propres à ces extensions. Pour un bloc destiné à être traduit via l’interface de String Translation de WPML plutôt que via des fichiers .po traditionnels, une approche alternative consiste à faire générer côté serveur, par PHP, un objet JavaScript contenant les chaînes déjà traduites via pll__() ou l’équivalent WPML, injecté dans la page via wp_localize_script(), puis consommé directement par le code JavaScript du bloc sans repasser par le système de fichiers JSON.
wp_localize_script('mon-bloc-view-script', 'monBlocI18n', [
'stockDisponible' => pll__('Plus que {n} en stock'),
'ruptureStock' => pll__('Rupture de stock'),
]);
Ce second mécanisme demande un peu plus de code de liaison, mais il s’intègre plus naturellement dans un flux de traduction déjà construit autour de Polylang, sans dépendre de fichiers .po gérés séparément.
La question à se poser dès la conception d’un bloc interactif : ce texte pourra-t-il changer sans recharger la page ? Si oui, il doit être traduisible dès l’écriture du fichier
view.js, jamais ajouté après coup une fois le bloc déjà en production.
Le résultat sur ce projet
Une fois les six chaînes concernées reliées à leur traduction via l’approche wp_localize_script(), combinée à la traduction déjà existante des chaînes équivalentes côté PHP, le message d’état du bloc s’est affiché correctement dans chacune des trois langues du site, y compris lors des mises à jour dynamiques déclenchées sans rechargement de page.
En résumé
L’Interactivity API ouvre des possibilités d’interaction précieuses, mais elle déplace une partie du texte affiché hors du circuit habituel de traduction PHP, un point que les mécanismes classiques de Polylang ou WPML ne couvrent pas automatiquement. Anticiper ce besoin dès la conception du bloc, plutôt que de le découvrir une fois le site déjà multilingue, évite un correctif après coup souvent plus coûteux que la précaution initiale.