Si vous avez déjà vu passer dans vos logs un “Polylang fatal error” avec une mention de lingotek-translation, vous avez probablement eu droit à un écran blanc, une erreur 500, ou un back-office inaccessible juste après une mise à jour.

Le point clé : Polylang fonctionne, mais un autre composant (souvent Lingotek Translation) l’appelle au mauvais moment, avec une version incompatible, ou sur une installation partiellement initialisée.

Le problème

Le message exact varie selon les versions, mais on retrouve très souvent des fatal errors de ce style (exemples réalistes) :

Fatal error: Uncaught Error: Call to undefined function pll_current_language()
in /wp-content/plugins/lingotek-translation/includes/class-lingotek.php:123
Stack trace:
#0 /wp-includes/class-wp-hook.php(324): Lingotek->bootstrap()
#1 /wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#2 /wp-includes/plugin.php(517): WP_Hook->do_action()
#3 /wp-settings.php(700): do_action('plugins_loaded')
thrown in /wp-content/plugins/lingotek-translation/includes/class-lingotek.php on line 123
Fatal error: Uncaught Error: Class "PLL_Model" not found
in /wp-content/plugins/lingotek-translation/vendor/somefile.php:77
thrown in /wp-content/plugins/lingotek-translation/vendor/somefile.php on line 77
Fatal error: Uncaught TypeError: strpos(): Argument #1 ($haystack) must be of type string, null given
in /wp-content/plugins/polylang/include/some-file.php:456
Stack trace: ...

Où ça apparaît :

  • Front-end : erreur 500 / page blanche dès que vous chargez une page.
  • Admin : “Il y a eu une erreur critique sur ce site.”, parfois uniquement sur Pages / Articles / Traductions.
  • Cron / WP-Cron : erreurs dans les logs lors d’une tâche planifiée (synchronisation Lingotek, import/export, etc.).
  • REST API / AJAX : erreurs sur des requêtes Elementor/Divi/Avada (prévisualisation, chargement de templates) car ces builders utilisent intensivement l’API REST.

Circonstances typiques :

  • Après une mise à jour de Polylang, Lingotek Translation, ou WordPress (vous êtes sur WordPress 6.9.4 en avril 2026).
  • Après l’activation de Lingotek Translation sur un site déjà multilingue.
  • Après une migration (staging → production) où des options ou des tables ont été partiellement copiées.
  • Après l’ajout d’un snippet (thème enfant / plugin de snippets) qui appelle Polylang “trop tôt”.

À qui s’adresse ce guide : si vous débutez, vous allez apprendre à récupérer un site cassé sans paniquer, isoler un conflit, lire les logs, et appliquer des corrections sûres (sans modifier WordPress ni les plugins). Si vous êtes intermédiaire/pro, vous repartirez avec un mu-plugin de garde-fou et une méthode reproductible.

Résumé rapide

  • Un fatal error “Polylang + Lingotek” vient le plus souvent d’un appel à Polylang avant qu’il soit chargé (hook trop tôt) ou d’une incompatibilité de versions.
  • Commencez par désactiver Lingotek Translation (ou tous les plugins sauf Polylang) pour confirmer le conflit.
  • Activez les logs avec WP_DEBUG_LOG et récupérez la ligne exacte (fichier + numéro de ligne).
  • Si un snippet appelle pll_current_language() dans plugins_loaded ou pire, au chargement du fichier, déplacez-le sur wp_loaded / init avec des garde-fous.
  • Réparez ensuite les “strings” et purgez les caches (plugin de cache, OPcache, cache builder) puis réenregistrez les permaliens.
  • Si le site reste instable, utilisez Health Check et Query Monitor pour isoler précisément le composant fautif.

Les symptômes

Voici ce que vous verrez le plus souvent sur un site WordPress 6.9.4 :

  • Erreur 500 côté visiteur, et/ou écran blanc.
  • “Il y a eu une erreur critique sur ce site” dans l’admin, parfois accompagné d’un e-mail automatique de WordPress.
  • Impossible d’accéder à Traductions (menus Polylang) ou à l’éditeur (Gutenberg) sur des contenus traduits.
  • Prévisualisation Elementor qui tourne en boucle, ou modules Divi 5 qui ne chargent plus (requêtes REST en erreur).
  • Dans la console navigateur : erreurs 500 sur /wp-json/ ou sur admin-ajax.php.
  • Dans les logs PHP : “Call to undefined function pll_*”, “Class PLL_* not found”, “Cannot redeclare…”, ou des TypeError après passage à PHP 8.1+.

Tableau de diagnostic rapide (très utile quand vous devez décider quoi tester en premier) :

Symptôme Cause probable Vérification Solution
Erreur 500 dès l’accueil Fatal error au chargement d’un plugin (Lingotek) Consultez wp-content/debug.log ou logs serveur Désactivez Lingotek, puis réactivez-le après mise à jour/patch (Solution 1)
Admin OK, mais éditeur/preview KO REST API cassée par un hook Polylang/Lingotek Testez /wp-json/, console navigateur Corriger le hook “trop tôt” (Solution 2)
Langue “null” / chaînes non traduites Strings Polylang corrompues / cache persistant Polylang > Traductions de chaînes, purge cache Réparer strings + purge + permaliens (Solution 3)
Ça marche en local, pas en prod OPcache / version PHP / plugin cache Redémarrage PHP-FPM, purge cache, vérifier PHP 8.1+ Purge + alignement versions + désactivation cache temporaire

Pourquoi ça arrive

Explication simple : Polylang expose des fonctions (ex : pll_current_language()) et des classes internes. Si un autre plugin (souvent Lingotek Translation) les utilise avant que Polylang ait fini de se charger, PHP ne les trouve pas et votre site plante.

Voici ce qui se passe en coulisses (version technique) :

  • WordPress charge les plugins, puis déclenche des actions (un “hook” d’action est un point d’accroche où du code s’exécute). Exemple : plugins_loaded, init, wp_loaded.
  • Polylang n’expose pas toutes ses fonctions/classes dès la première milliseconde. Certaines choses sont initialisées au fil des hooks.
  • Si Lingotek (ou un snippet) s’accroche sur plugins_loaded et appelle immédiatement pll_current_language(), vous pouvez tomber sur un “undefined function”.
  • Avec PHP 8.1+, des erreurs qui étaient des “warnings” deviennent des TypeError (types stricts). Un null inattendu peut devenir fatal.

Causes classées du plus fréquent au plus rare :

  • Incompatibilité de versions : Lingotek Translation pas à jour par rapport à Polylang (ou l’inverse).
  • Ordre de chargement / hook trop tôt : appel à une API Polylang avant initialisation.
  • Snippet cassé dans le thème enfant / plugin de snippets qui suppose que Polylang est toujours actif.
  • Cache persistant (OPcache, cache page, cache objet) qui garde un état “mixé” après mise à jour.
  • Migration partielle : options Polylang/Lingotek incohérentes, chaînes en double, tables manquantes.
  • Conflit avec un builder : Elementor/Divi/Avada déclenchent des routes REST/AJAX qui passent dans un chemin de code non testé.

Prérequis avant de commencer

Avant toute manipulation :

  • Sauvegardez fichiers + base de données. Ne testez jamais “au hasard” sur production.
  • Si possible, travaillez sur un staging (copie de votre site).
  • Vérifiez vos versions : WordPress 6.9.4, PHP recommandé 8.1+ (8.2/8.3 souvent OK selon hébergeur).

Outils utiles (gratuits) :

Activer les logs WordPress (recommandé pour ce dépannage) :

  • Ouvrez wp-config.php (à la racine) et ajoutez/ajustez les constantes ci-dessous.
  • Ne laissez pas l’affichage des erreurs en production (risque de fuite d’infos). Loggez, n’affichez pas.
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
/* Sécurité : on évite d'afficher les erreurs aux visiteurs */
define('WP_DEBUG_DISPLAY', false);

Documentation officielle : Debugging in WordPress.


Solution 1 : Isoler Lingotek (et vérifier la compatibilité Polylang)

Quand je tombe sur “Polylang fatal error maybe with lingotek-translation”, je commence presque toujours par ça : confirmer que Lingotek est bien le déclencheur, puis aligner les versions.

Étape A — Confirmer le conflit (sans casser le site)

Si vous avez encore accès à l’admin :

  1. Allez dans Extensions > Extensions installées.
  2. Désactivez Lingotek Translation.
  3. Testez le front + l’admin.

Si vous n’avez plus accès à l’admin (erreur critique) :

  1. Connectez-vous en FTP/SFTP ou via le gestionnaire de fichiers de l’hébergeur.
  2. Allez dans wp-content/plugins/.
  3. Renommez le dossier lingotek-translation en lingotek-translation.off.

WordPress désactivera automatiquement le plugin au prochain chargement.

Étape B — Mettre à jour proprement (Polylang + Lingotek)

Une fois le site revenu :

  • Mettez à jour Polylang et Lingotek Translation depuis Tableau de bord > Mises à jour.
  • Si une mise à jour échoue, réinstallez le plugin proprement (supprimer puis réinstaller). Sur un site multilingue, faites-le sur staging d’abord.

Sources officielles :

Code AVANT (cassé) — dépendance non vérifiée

Le cas classique : Lingotek (ou un autre plugin/snippet) suppose que Polylang est actif, et appelle une fonction Polylang sans garde-fou.

<?php
// Exemple typique : appel direct sans vérifier si Polylang est chargé.
$lang = pll_current_language(); // Fatal si Polylang n'est pas prêt (ou désactivé)
update_option('my_last_lang', $lang);

Code APRÈS (corrigé) — garde-fous + timing

Vous ne modifiez pas Lingotek directement. À la place, vous pouvez ajouter un “garde-fou” côté site pour éviter le fatal si un snippet maison est impliqué.

Où coller ce code : idéalement dans un mu-plugin (plugin “must-use”, chargé automatiquement). Créez le fichier :

  • wp-content/mu-plugins/bpcab-polylang-guards.php
<?php
/**
 * Plugin Name: BPCAB - Garde-fous Polylang
 * Description: Évite des fatals si du code appelle Polylang trop tôt ou si Polylang est désactivé.
 * Author: Votre équipe
 * Version: 1.0.0
 */

if (!defined('ABSPATH')) {
	exit;
}

/**
 * On attend que WordPress ait chargé les plugins, puis on exécute plus tard si nécessaire.
 * wp_loaded arrive après init et après la mise en place de l'environnement WordPress.
 */
add_action('wp_loaded', function () {

	// Polylang expose des fonctions globales pll_* quand il est actif et initialisé.
	if (!function_exists('pll_current_language')) {
		// Polylang n'est pas actif ou pas prêt : on sort sans casser le site.
		return;
	}

	$lang = pll_current_language();

	// Exemple d'utilisation sûre.
	if (is_string($lang) && $lang !== '') {
		update_option('my_last_lang', $lang, false);
	}
}, 20);

Pourquoi ça corrige :

  • function_exists() évite l’appel fatal si Polylang est absent/non chargé.
  • wp_loaded réduit les risques d’appeler Polylang pendant sa phase d’initialisation.
  • Le mu-plugin est plus fiable qu’un snippet dans un thème (un thème peut être changé, un builder peut surcharger des templates, etc.).

Note : si le fatal vient uniquement de Lingotek, ce garde-fou ne patchera pas son code interne. Il sert surtout à éliminer les snippets “cachés” (thème enfant, plugin de snippets) qui aggravent la situation. Pour Lingotek, la résolution durable est généralement : mise à jour ou désactivation (voir la section “Variante / alternative”).


Solution 2 : Corriger un code qui appelle Polylang trop tôt (hooks)

J’ai souvent vu ce bug sur des sites où quelqu’un a copié un bout de code “multilingue” dans functions.php (thème enfant) ou dans un plugin de snippets. Ça marche… jusqu’au jour où une mise à jour change le timing d’initialisation.

Définition rapide :

  • Un hook est un point d’accroche dans WordPress.
  • Une action exécute du code à un moment donné (ex : init).
  • Un filtre modifie une valeur (ex : the_content).

Référence officielle : Hooks (Actions and Filters).

Cas fréquent : appel au chargement du fichier (le pire timing)

Code AVANT (cassé). On le voit dans functions.php ou un plugin de snippets :

<?php
// Mauvaise pratique : ce code s'exécute dès l'inclusion du fichier.
$current = pll_current_language(); // Fatal si Polylang n'est pas encore prêt
$GLOBALS['my_lang'] = $current;

Code APRÈS (corrigé). Où coller : dans functions.php d’un thème enfant (Divi/Avada/Hello Elementor) ou, mieux, dans un petit plugin custom.

<?php
/**
 * Initialise une variable globale de langue de façon sûre.
 * À coller dans functions.php du thème enfant, ou dans un plugin custom.
 */

add_action('wp_loaded', function () {

	if (!function_exists('pll_current_language')) {
		// Polylang absent ou désactivé : on définit une valeur par défaut.
		$GLOBALS['my_lang'] = get_locale();
		return;
	}

	$lang = pll_current_language();

	$GLOBALS['my_lang'] = (is_string($lang) && $lang !== '') ? $lang : get_locale();
}, 20);

Cas builder (Divi 5 / Elementor / Avada) : REST/AJAX exécuté sans contexte “front”

Les builders déclenchent des requêtes qui ne ressemblent pas à une page normale. Si votre code suppose “on est sur le front”, vous pouvez casser l’éditeur.

Code AVANT (cassé) : exécution sur toutes les requêtes, y compris REST/AJAX.

<?php
add_action('init', function () {
	// Exemple : redirection selon langue, mais déclenchée partout.
	if (function_exists('pll_current_language') && pll_current_language() === 'en') {
		wp_redirect(home_url('/en/'));
		exit;
	}
});

Code APRÈS (corrigé) : on évite REST/AJAX/admin, et on limite aux pages front.

<?php
add_action('template_redirect', function () {

	// Sécurité : pas de redirection en admin.
	if (is_admin()) {
		return;
	}

	// Évite de casser l'éditeur Elementor/Divi/Avada (REST/AJAX).
	if (wp_doing_ajax() || (defined('REST_REQUEST') && REST_REQUEST)) {
		return;
	}

	if (!function_exists('pll_current_language')) {
		return;
	}

	$lang = pll_current_language();
	if ($lang !== 'en') {
		return;
	}

	// Exemple : redirection contrôlée.
	$target = home_url('/en/');

	// Évite les boucles de redirection.
	if (home_url(add_query_arg([], $GLOBALS['wp']->request)) === $target) {
		return;
	}

	wp_safe_redirect($target, 302);
	exit;
}, 20);

Pourquoi ça corrige :

  • template_redirect est un hook “front” plus adapté à une redirection que init.
  • Les garde-fous wp_doing_ajax() et REST_REQUEST évitent de casser les appels techniques des builders.
  • wp_safe_redirect() limite les risques de redirection vers un domaine non autorisé (sécurité).

Références officielles :


Solution 3 : Réparer les “strings”, réinitialiser les caches et régénérer les règles

Quand le fatal error a disparu mais que vous avez encore des comportements bizarres (langue “null”, chaînes non traduites, routes REST instables), le problème est souvent un état incohérent : cache + options + règles de réécriture.

Étape A — Vider les caches (dans le bon ordre)

Ordre que j’applique en pratique (sinon vous pouvez “croire” que ça ne marche pas) :

  1. Purge du cache du plugin (WP Rocket, LiteSpeed Cache, W3TC, etc.).
  2. Si vous avez un cache serveur (LiteSpeed, Nginx FastCGI, Varnish), purge côté hébergeur.
  3. Redémarrage PHP-FPM / purge OPcache si l’hébergeur le permet (sinon, attendez quelques minutes).
  4. Hard refresh navigateur (Ctrl+F5) ou test en navigation privée.

Avec Elementor/Divi/Avada, pensez aussi à :

  • Elementor : “Regénérer CSS & Données” (selon version) et vider le cache interne.
  • Divi 5 : vider le cache statique/performances si activé.
  • Avada : vider le cache “Fusion” si présent.

Étape B — Réenregistrer les permaliens (rewrite rules)

Quand des routes traduites changent (slugs, langues, répertoires), WordPress peut garder de vieilles règles de réécriture.

  1. Allez dans Réglages > Permaliens.
  2. Sans rien changer, cliquez Enregistrer les modifications.

Référence officielle : flush_rewrite_rules() (à ne pas appeler à chaque page, uniquement lors d’un changement).

Étape C — Réparer les “strings” Polylang (cas des traductions de chaînes)

Polylang gère des “strings” (chaînes) pour traduire des textes qui ne viennent pas d’un article (ex : slogan, widgets, options de thème). Après un crash ou une migration, j’ai déjà vu des strings dupliquées ou incomplètes.

Sans code (recommandé débutant) :

  • Allez dans Langues > Traductions de chaînes.
  • Recherchez les chaînes problématiques, réenregistrez-les si nécessaire.

Avec code (si vous avez un thème/plugin qui enregistre des strings) : le bug vient souvent d’un enregistrement trop tôt.

Code AVANT (cassé) : enregistrement de string au chargement du fichier (ou sur un hook trop tôt).

<?php
// Mauvais timing : Polylang peut ne pas être prêt.
pll_register_string('Mon slogan', get_option('blogdescription'), 'Theme');

Code APRÈS (corrigé) : enregistrement sur init avec garde-fou.

Où coller : functions.php du thème enfant, ou plugin custom.

<?php
add_action('init', function () {

	// pll_register_string() n'existe que si Polylang est actif.
	if (!function_exists('pll_register_string')) {
		return;
	}

	$desc = get_option('blogdescription');
	if (!is_string($desc)) {
		$desc = '';
	}

	// On enregistre une chaîne stable (clé + groupe) pour éviter les doublons.
	pll_register_string('site_tagline', $desc, 'Theme');
}, 20);

Pourquoi ça corrige :

  • Vous évitez l’appel fatal si Polylang est désactivé.
  • Vous utilisez une clé stable (site_tagline) au lieu d’un libellé variable, ce qui limite les doublons.
  • Le hook init est un bon compromis : WordPress est initialisé et Polylang est généralement prêt à enregistrer des strings.

Vérifications après correction

Une fois une solution appliquée, testez systématiquement :

  • Front : page d’accueil + une page traduite + une page non traduite.
  • Admin : édition d’un article dans chaque langue, et ouverture des écrans Polylang.
  • REST API : ouvrez https://votre-site.tld/wp-json/ (vous devez obtenir du JSON, pas une 500).
  • Builders :
    • Elementor : prévisualisation d’une page traduite.
    • Divi 5 : chargement du Visual Builder sur une page traduite.
    • Avada : chargement du builder Fusion sur une page traduite.
  • Logs : wp-content/debug.log doit cesser d’ajouter des fatals à chaque hit.

Si vous aviez activé WP_DEBUG, gardez WP_DEBUG_LOG le temps de valider, puis désactivez l’affichage public des erreurs.


Si ça ne marche toujours pas

Procédure que j’utilise quand le site reste instable, étape par étape (sans supposer que vous soyez développeur) :

1) Récupérer l’erreur exacte

  • Lisez wp-content/debug.log (si activé).
  • Sinon, consultez les logs PHP de l’hébergeur (souvent “error_log”).
  • Copiez : message + fichier + ligne. Sans ça, on devine.

2) Mode “Troubleshooting” (Health Check)

Activez Health Check, puis :

  • Activez le mode dépannage.
  • Désactivez tous les plugins sauf Polylang.
  • Testez. Si OK, réactivez Lingotek Translation seul, puis les autres un par un.

Ça évite le piège classique : “je désactive un plugin et je casse le site pour tout le monde”.

3) Vérifier la version PHP et la mémoire

  • PHP : minimum recommandé 8.1. En dessous, vous multipliez les incompatibilités modernes.
  • Mémoire : si vous voyez des erreurs de type “Allowed memory size exhausted”, augmentez la mémoire WP.

Référence officielle (mémoire) : Increasing memory allocated to PHP.

4) Query Monitor : repérer le hook / composant fautif

  • Installez Query Monitor.
  • Ouvrez la page qui casse.
  • Regardez “PHP Errors” et “Hooks & Actions” pour voir ce qui s’exécute juste avant le crash.

5) Conflit cache / OPcache

Si vous avez corrigé du code mais que le fatal persiste “comme si rien n’avait changé”, j’ai deux suspects :

  • OPcache (PHP) garde une version compilée d’un fichier.
  • Un plugin de cache sert une page HTML “ancienne” ou une réponse REST en cache.

Testez en désactivant temporairement le cache, et si possible redémarrez PHP côté hébergeur.

6) Dernier recours : désactiver Polylang, puis réactiver

Attention : sur certains sites, désactiver/réactiver peut déclencher des synchronisations ou des régénérations. Faites-le sur staging si vous pouvez.


Pièges et erreurs courantes

Symptôme Cause probable Solution recommandée
Fatal “undefined function pll_current_language()” Code exécuté trop tôt / Polylang désactivé Déplacer sur wp_loaded + function_exists() (Solution 2)
Vous collez le code “au mauvais endroit” Snippet mis dans un fichier plugin, mais hors balises PHP, ou dans le thème parent Utiliser thème enfant ou mu-plugin ; vérifier <?php et l’emplacement
Erreur après modification : “Parse error” Point-virgule manquant, parenthèse oubliée Revenir en arrière via FTP, corriger la syntaxe, utiliser un éditeur avec coloration
L’éditeur Elementor/Divi ne charge plus Redirection / logique de langue exécutée sur REST/AJAX Garde-fous REST_REQUEST et wp_doing_ajax() (Solution 2)
Ça marche après désactivation, puis recasse après réactivation Incompatibilité de versions Polylang/Lingotek Mettre à jour, sinon remplacer Lingotek (Solution 1 + Variante)
Le bug “revient” malgré la correction Cache serveur/OPcache non purgé Purge cache + redémarrage PHP-FPM si possible (Solution 3)
Permaliens traduits en 404 Rewrite rules obsolètes Réenregistrer Permaliens (Solution 3)

Deux erreurs que je vois tout le temps :

  • Tester directement en production sans sauvegarde. Un simple “Parse error” peut vous bloquer l’admin.
  • Utiliser un hook inadapté : init pour une redirection, ou du code au chargement du fichier. Ça “marche” jusqu’au jour où ça ne marche plus.

Variante / alternative

Alternative sans code : remplacer Lingotek Translation

Si votre besoin est “traduire et gérer des langues” mais que Lingotek est la source d’instabilité, la solution la plus simple est parfois de :

  • Garder Polylang pour la structure multilingue.
  • Utiliser un autre flux de traduction (manuel, ou un service compatible) au lieu de Lingotek.

Je le dis franchement : quand un plugin d’intégration de traduction externe n’est plus aligné avec les versions récentes, vous pouvez passer des heures à “patcher” alors que le vrai gain est de simplifier.

Alternative développeur : encapsuler l’accès à Polylang via une fonction “safe”

Si vous avez plusieurs endroits où vous appelez Polylang, centralisez la logique dans une fonction utilitaire. Ça réduit les erreurs lors de futures mises à jour.

Où coller : mu-plugin (recommandé) ou plugin custom.

<?php
/**
 * Retourne une langue courante de façon robuste.
 * - Si Polylang est disponible : on l'utilise.
 * - Sinon : fallback sur la locale WordPress.
 */
function bpcab_get_current_language_code(): string
{
	if (function_exists('pll_current_language')) {
		$lang = pll_current_language();
		if (is_string($lang) && $lang !== '') {
			return $lang;
		}
	}

	// Fallback : ex "fr_FR" - à adapter si vous voulez "fr".
	return (string) get_locale();
}

Ensuite, remplacez partout pll_current_language() par bpcab_get_current_language_code().


Éviter ce problème à l’avenir

  • Ne modifiez jamais le core (WordPress) ni un plugin directement. Toute mise à jour écrasera vos changements.
  • Évitez de coller des snippets critiques dans le thème parent. Utilisez un thème enfant ou un mu-plugin.
  • Quand vous utilisez Polylang dans du code :
    • Vérifiez toujours function_exists('pll_current_language') / function_exists('pll_register_string').
    • Choisissez un hook cohérent : init pour enregistrer des choses, wp_loaded pour lire l’état final, template_redirect pour les redirections front.
  • Après une mise à jour importante :
    • Purge cache plugin + serveur.
    • Réenregistrez les permaliens si vous avez touché aux langues/slugs.
  • Gardez un staging. Sur les sites multilingues, c’est quasiment obligatoire si vous avez des intégrations externes.

Référence PHP (comportements TypeError) : PHP errors (PHP 7+ et comportements modernes). Même si la page parle de “PHP 7+”, l’idée est la même : les erreurs de type sont plus strictes, et PHP 8.1+ les rend plus visibles.


Ressources


Questions fréquentes

Comment savoir si c’est Polylang ou Lingotek qui casse le site ?

Regardez le fichier dans le fatal error (dans debug.log). Si le chemin pointe vers /plugins/lingotek-translation/, Lingotek déclenche l’erreur. Si ça pointe vers votre thème enfant ou un plugin de snippets, c’est votre code qui appelle Polylang au mauvais moment.

Je n’ai pas de debug.log. C’est normal ?

Oui, si WP_DEBUG_LOG n’est pas activé, ou si le serveur n’a pas les droits d’écriture sur wp-content/. Activez les constantes et vérifiez les permissions.

Est-ce que désactiver Lingotek va supprimer mes traductions ?

En général, vos contenus traduits restent dans WordPress (ce sont des posts/pages). Ce qui peut disparaître, ce sont des fonctionnalités de synchronisation avec Lingotek. Testez sur staging si vous dépendez fortement de ce flux.

Pourquoi l’erreur arrive “après une mise à jour”, alors que je n’ai rien changé ?

Parce qu’un plugin peut changer son timing d’initialisation, ou devenir plus strict (PHP 8.1+). Un code qui passait “par chance” peut devenir fatal du jour au lendemain.

Je peux corriger en modifiant directement le plugin Lingotek ?

Techniquement oui, mais vous perdez la correction à la prochaine mise à jour. Si vous devez patcher, faites-le via un fork maintenu (avancé) ou remplacez l’intégration. Pour un site débutant, je déconseille la modification directe.

Quel hook est le plus sûr pour lire la langue courante ?

Sur la plupart des sites, wp_loaded est un bon point de lecture “tardif”. Pour modifier le rendu du contenu, utilisez plutôt des filtres comme the_content (en vérifiant la compatibilité REST/AJAX si nécessaire).

Elementor/Divi/Avada sont-ils compatibles avec Polylang ?

Oui dans la majorité des cas, mais les builders déclenchent beaucoup de REST/AJAX. Le piège vient souvent de vos redirections ou conditions de langue qui s’exécutent sur ces requêtes techniques. Les garde-fous de la Solution 2 évitent précisément ça.

J’ai corrigé le code, mais l’erreur continue. Pourquoi ?

Cache. Purgez le cache plugin + serveur, et si possible OPcache. J’ai déjà vu des hébergements garder un fichier PHP “ancien” plusieurs minutes.

Dois-je réenregistrer les permaliens après avoir touché aux langues ?

Oui, dès que vous changez la structure d’URL (langue en répertoire, slugs traduits, etc.). C’est rapide et ça règle beaucoup de 404.

Est-ce que PHP 8.1 est obligatoire ?

Sur WordPress 6.9.4, PHP 8.1+ est le minimum recommandé pour rester compatible avec l’écosystème actuel. En dessous, vous augmentez fortement le risque d’erreurs et de plugins non supportés.