Deux attributs lang différents peuvent parfaitement cohabiter sur une même page web, chacun valide pris isolément, sans provoquer la moindre erreur de validation HTML. C’est exactement ce qui s’est produit sur un site institutionnel traduit en anglais avec Polylang, une fois un widget de chat en ligne tiers ajouté à toutes les pages via un script embarqué.
Le signalement initial venait d’un test d’accessibilité mené avec un lecteur d’écran : la voix de synthèse changeait brutalement d’accent, voire de langue complète, au moment où le focus clavier entrait dans la zone du widget de chat, rendant l’annonce du contenu du widget incompréhensible pour l’utilisatrice qui menait le test.
Symptôme : la synthèse vocale change de langue sans raison apparente
Le site, entièrement traduit en anglais sur ses pages /en/, affichait un attribut lang="en" cohérent sur la balise html de chaque page grâce à get_language_attributes(). Pourtant, dès que le lecteur d’écran atteignait le widget de chat, positionné en bas à droite de chaque page via une iframe injectée par un script tiers, la voix de synthèse basculait vers un accent français, y compris sur les pages anglaises du site.
Diagnostic : l’iframe du widget porte son propre attribut lang
L’inspection du code source, une fois le widget de chat chargé, révèle que le fournisseur du service injecte une iframe avec son propre document HTML complet, incluant sa propre balise html lang="fr" codée en dur côté widget, indépendante de la langue de la page qui l’embarque. Les lecteurs d’écran respectent l’attribut lang le plus précis dans l’arbre du document : à l’intérieur d’une iframe, c’est l’attribut lang de son propre document qui prévaut, et non celui de la page parente.

<!-- Extrait du document chargé DANS l'iframe du widget, hors contrôle du site -->
<html lang="fr">
<body>
<div class="widget-chat">Bonjour, comment puis-je vous aider ?</div>
</body>
</html>
Le site lui-même n’avait aucune prise directe sur ce document : il vivait entièrement dans une origine différente, servie par le fournisseur du widget, chargée par un simple appel de script fourni en autant de lignes à coller dans le thème.
Le correctif : configurer la langue côté widget, pas côté thème
La plupart des widgets de chat de ce type exposent un paramètre de langue dans leur configuration, souvent sous forme d’un attribut de script ou d’un appel JavaScript d’initialisation. Le correctif a consisté à transmettre dynamiquement la langue courante de la page WordPress à ce paramètre, plutôt que de laisser le widget sur sa langue par défaut.
<script>
window.widgetChatConfig = {
lang: '<?php echo esc_js( function_exists( 'pll_current_language' ) ? pll_current_language() : 'fr' ); ?>'
};
</script>
<script src="https://cdn.widget-chat-exemple.com/loader.js" async></script>
Cette configuration transmet à l’initialisation du widget la langue active de la page, déterminée via la fonction pll_current_language() exposée par Polylang, permettant au fournisseur de générer son iframe avec un attribut lang cohérent avec le reste de la page.
Ce qu’il faut vérifier avant d’adopter un widget tiers multilingue
- Le widget propose-t-il un paramètre de langue explicite dans sa documentation d’intégration ?
- Ce paramètre est-il transmis dynamiquement, ou figé une fois pour toutes dans le code du thème ?
- Un test au clavier et au lecteur d’écran, sur chaque langue du site, confirme-t-il l’attribut
langréellement rendu dans l’iframe ?
Pourquoi cette catégorie de bug passe inaperçue en test visuel
Rien dans le rendu visuel de la page ne trahit ce problème : le texte du widget reste lisible, aucune erreur de mise en page ne survient, et la validation HTML du document parent ne détecte rien puisque son propre attribut lang reste correct. Seul un test avec une technologie d’assistance, ou une inspection manuelle du contenu de l’iframe, permet de repérer la contradiction entre les deux documents imbriqués.
En résumé
Un widget tiers embarqué en iframe constitue un document HTML à part entière, avec son propre attribut lang qui prévaut sur celui de la page hôte pour les technologies d’assistance. Un site multilingue qui intègre ce type de widget doit vérifier, langue par langue, que le paramètre de langue du widget est bien synchronisé avec celui de la page, sous peine de brouiller silencieusement l’expérience des utilisateurs de lecteurs d’écran.