# Pourquoi le sélecteur de langue s’est cassé après une mise à jour d’Elementor

> Un sélecteur de langue personnalisé a cessé de fonctionner après une mise à jour du page builder. Diagnostic complet d'un conflit qui peut toucher beaucoup de sites.

- Auteur : Clément Hadrot
- Publié le : 2025-09-24
- Mis à jour le : 2025-09-24
- Catégorie : Multilingue
- URL : https://wpmoderne.dev.wordpress-developpement.fr/multilingue/panne-selecteur-langue-elementor/

## L’essentiel

- Le widget personnalisé s'appuyait sur une classe CSS renommée par Elementor 3.20
- Le diagnostic est passé par la console réseau puis l'inspecteur DOM
- Le correctif évite de dépendre de classes internes du page builder

Le mardi matin, le support d'un client gérant un réseau de cliniques dentaires nous signale un problème simple en apparence : le sélecteur de langue en haut du site, qui permet de passer du français au néerlandais, ne réagit plus au clic. Aucune erreur visible côté visiteur, le menu semble juste inerte. Premier réflexe : vérifier si une mise à jour a eu lieu récemment. Le journal de maintenance du site indique une mise à jour d'Elementor vers la version 3.20 la veille au soir, en dehors de tout changement lié à WPML ou au sélecteur lui-même.

Cet article ne revient pas sur la construction du sélecteur, déjà couverte ailleurs, mais uniquement sur le diagnostic de ce conflit précis, qui illustre un type de panne fréquent avec les page builders : une mise à jour non liée en apparence casse un composant qui dépendait, sans le savoir vraiment, d'un détail d'implémentation interne.

## Symptôme

Le sélecteur de langue, un widget personnalisé développé sur mesure et intégré via un widget Elementor custom, affiche correctement les drapeaux et les libellés de langue, mais aucun clic ne déclenche la navigation attendue. Aucune erreur n'apparaît dans la console JavaScript du navigateur au premier chargement, ce qui oriente d'abord vers une fausse piste : un problème de cache ou de CDN.

## Diagnostic

Après avoir écarté le cache (test en navigation privée, purge du cache Elementor via **Elementor → Outils → Régénérer les fichiers CSS**, sans effet), l'inspection du DOM révèle la cause réelle. Le widget personnalisé ciblait, dans son fichier JavaScript, un sélecteur CSS basé sur une classe interne générée par Elementor pour structurer sa mise en page :

```
document.querySelectorAll('.elementor-widget-container .lang-switcher-item')
    .forEach(function (item) {
        item.addEventListener('click', function (e) {
            e.preventDefault();
            window.location.href = item.dataset.langUrl;
        });
    });
```

Un examen du DOM généré après la mise à jour montre que la classe `elementor-widget-container` est toujours présente, mais que la structure imbriquée autour a changé : Elementor 3.20 a introduit une refonte partielle du rendu de ses conteneurs (liée à la généralisation des Flexbox Container), ajoutant un niveau de `div` supplémentaire entre le widget et son contenu dans certains contextes de mise en page. Le sélecteur JavaScript, en soi toujours valide, ne trouvait simplement plus les éléments `.lang-switcher-item` attendus, car ceux-ci étaient désormais rendus dans une structure DOM légèrement différente pour les widgets custom utilisant l'API `render_content` historique plutôt que les nouveaux templates Vue d'Elementor.

> Un widget qui fonctionne parfaitement pendant deux ans peut casser du jour au lendemain sans qu'une seule ligne de son propre code n'ait changé : c'est le risque de tout composant qui s'appuie, même indirectement, sur la structure interne d'un page builder tiers.

## Correctif

> L'essentiel à retenir : Le widget personnalisé s'appuyait sur une classe CSS renommée par Elementor 3.20 ; Le diagnostic est passé par la console réseau puis l'inspecteur DOM ; Le correctif évite de dépendre de classes internes du page builder

La correction retenue évite justement de dépendre à nouveau d'une classe générée par Elementor. Plutôt que de cibler `.elementor-widget-container`, le widget a été modifié pour attacher un identifiant stable défini par le développeur lui-même, garanti indépendant de toute mise à jour du page builder :

```
<div class="ldc-lang-switcher" data-widget="lang-switcher">
    <a href="#" class="lang-switcher-item" data-lang-url="/en/">EN</a>
    <a href="#" class="lang-switcher-item" data-lang-url="/nl/">NL</a>
</div>

<script>
document.querySelectorAll('.ldc-lang-switcher .lang-switcher-item')
    .forEach(function (item) {
        item.addEventListener('click', function (e) {
            e.preventDefault();
            window.location.href = item.dataset.langUrl;
        });
    });
</script>
```

Le conteneur racine `.ldc-lang-switcher` est un choix de nommage propre au projet, jamais généré ni modifié par Elementor, ce qui rend le sélecteur JavaScript insensible à toute future évolution de la structure interne du page builder.

## Prévention

- Ne jamais cibler dans du code applicatif une classe CSS préfixée `elementor-`, même si elle semble stable depuis longtemps ;
- Encapsuler systématiquement les widgets personnalisés dans un conteneur portant une classe propre au projet, servant de point d'ancrage stable pour tout script ;
- Tester les mises à jour majeures d'Elementor sur un environnement de staging avant production, en particulier les versions qui touchent au rendu des containers (3.6 pour l'introduction des Flexbox Container, puis 3.20 pour leur généralisation) ;
- Ajouter un test de fumée automatisé (Playwright ou Cypress) qui clique sur le sélecteur de langue après chaque déploiement, pour détecter ce type de régression avant qu'un client ne le signale.

## En résumé

Cette panne n'avait rien à voir avec WPML ni avec la logique de traduction elle-même : c'était un problème d'intégration DOM, provoqué par une évolution interne d'un page builder tiers. Le réflexe utile ici a été de ne pas se précipiter sur une réinstallation de WPML ou une vérification des réglages de langue, mais de partir du symptôme observable (absence totale de réaction au clic) pour remonter méthodiquement jusqu'à la structure DOM réellement rendue après mise à jour.
