L’éditeur Gutenberg de WordPress ne se charge pas : liste de contrôle pratique

Cet article vous a aidé ?

L’éditeur Gutenberg « se charge » comme un ascenseur défectueux « arrive » : les portes ne s’ouvrent jamais, le spinner tourne sans fin et tout le monde commence à accuser le réseau comme s’il leur devait de l’argent.

Ce guide s’adresse aux cas où l’éditeur de blocs ne se charge pas, reste bloqué sur « Updating… », affiche une zone de contenu vide ou renvoie « The editor has encountered an unexpected error. ». Nous allons le diagnostiquer comme un SRE : isoler les variables, vérifier les hypothèses et changer une chose à la fois — parce que la production se fiche de votre bonne volonté.

Mode opératoire de diagnostic rapide

Si vous voulez le chemin le plus rapide vers le goulot d’étranglement, arrêtez de deviner et exécutez ceci dans l’ordre. L’objectif n’est pas de « tester des choses ». L’objectif est d’identifier quelle couche vous ment.

1) Vérifiez la console du navigateur en premier (les erreurs JS décident de tout)

  • Ouvrez la page de l’éditeur : /wp-admin/post-new.php ou /wp-admin/post.php?post=ID&action=edit.
  • DevTools → Console : cherchez les erreurs en rouge et les requêtes réseau échouées.
  • DevTools → Network : filtrez par wp-json, rest, block-editor, wp-admin/load-scripts.php et admin-ajax.php.

Décision : Si vous voyez « Échec de la récupération », « Jeton inattendu < dans le JSON », ou 401/403/5xx sur des endpoints REST, ce n’est pas un « problème Gutenberg ». C’est un problème d’API/auth/WAF/cache.

2) Vérifiez que l’API REST fonctionne depuis le serveur (ne faites pas confiance au navigateur)

Appelez /wp-json/ et un endpoint authentifié. Si votre serveur ne peut pas joindre lui‑même (ou renvoie du HTML là où il devrait y avoir du JSON), Gutenberg fera la tête.

Décision : Si /wp-json/ est cassé, réparez-le d’abord. Gutenberg en dépend comme l’oxygène dépend des poumons.

3) Désactivez les plugins et passez à un thème par défaut (chirurgical, pas émotionnel)

Faites-le via WP-CLI pour ne pas être exclu par l’interface que vous essayez de réparer.

Décision : Si la désactivation des plugins corrige le problème, réactivez par lots pour identifier le coupable. Si le changement de thème corrige, recherchez des scripts d’éditeur, des problèmes d’enqueue ou des entêtes CSP venant du thème.

4) Vérifiez le cache et les couches de sécurité (les suspects habituels)

  • Cache d’objets (Redis/Memcached)
  • Cache de page complet/CDN (Cloudflare, Fastly, varnish, microcache nginx)
  • Règles WAF bloquant wp-json ou les scripts admin
  • Entêtes CSP bloquant les scripts inline utilisés par WordPress

Décision : Si l’éditeur se charge en navigation privée mais pas en mode normal, cherchez des assets mis en cache, des service workers ou des extensions agressives. Si l’éditeur se charge en contournant le CDN/WAF, votre configuration edge est le méchant.

5) Confirmez que PHP et le stockage ne tombent pas en panne sous charge

Gutenberg effectue plus de requêtes que l’éditeur classique. Si PHP-FPM est saturé, le disque en thrashing ou l’opcache défaillant, l’éditeur paraît « bloqué » mais le vrai problème est la latence et les timeouts.

Décision : Si les logs côté serveur montrent des 502/504 ou des timeouts, réglez la capacité et la latence. Déboguer WordPress avec un disque mourant, c’est comme accorder un piano pendant un tremblement de terre.

Comment Gutenberg se charge réellement (et comment il casse)

Gutenberg est une application JavaScript embarquée dans wp-admin. Quand vous ouvrez l’éditeur, WordPress renvoie une page d’administration qui bootstrappe une pile de scripts (React, stores de données, registre de blocs, UI de l’éditeur) puis récupère le contenu et la configuration via des appels à l’API REST.

Cela signifie que vos modes de panne se regroupent généralement en quatre catégories :

  1. Échecs de bootstrap : les JS/CSS de l’éditeur ne se chargent pas, ou sont corrompus. Causes typiques : réécriture par cache/CDN, minifieurs, contenu mixte, CSP, mauvais content-type.
  2. Échecs API : wp-json bloqué, renvoyant du HTML au lieu du JSON, cookies d’authentification non acceptés, problèmes de nonce, 401/403 causés par le WAF, 5xx côté PHP.
  3. Échecs couche données : bizarreries du cache d’objets, erreurs de base de données, options autoload gonflées, requêtes lentes qui expirent.
  4. Échecs environnementaux : limite mémoire PHP, exhaustion d’opcache, disque plein, permissions, corruption de fichiers, ou un plugin de sécurité « utile » qui durcit les endpoints.

Quand l’éditeur de blocs « ne se charge pas », ce n’est souvent pas une erreur unique et catastrophique. C’est une chaîne : un script échoue, puis l’app JS ne peut plus appeler les endpoints REST, puis elle affiche un spinner indéfini parce qu’elle attend une promesse qui ne se résout jamais. Votre travail est de trouver le premier maillon cassé.

Une citation à garder : « L’espoir n’est pas une stratégie. » — General Gordon R. Sullivan.

Blague n°1 : Gutenberg est une application monopage vivant dans un monde multipage. C’est comme mettre un moteur de voiture de course dans un caddie et s’étonner qu’il couine.

Faits intéressants et bref historique (pourquoi cela revient souvent)

  • Gutenberg a été publié d’abord comme plugin avant d’être fusionné dans le cœur de WordPress, ce qui explique pourquoi certains sites traînent encore des résidus du plugin Gutenberg.
  • WordPress 5.0 (2018) a fait de l’éditeur de blocs le défaut, ce qui a soudainement poussé des millions d’environnements admin vers une charge JavaScript plus lourde.
  • L’éditeur de blocs s’appuie fortement sur l’API REST ; l’éditeur classique pouvait se débrouiller avec moins d’appels dynamiques.
  • wp-admin tolérait historiquement des configurations de cache « créatives » parce que la plupart des pages admin étaient rendues côté serveur. Gutenberg punit beaucoup plus vite les caches incorrects.
  • Les plugins de sécurité ont commencé à filtrer agressivement les endpoints JSON à mesure que les attaques REST se sont généralisées ; certains jeux de règles « résolvent » la sécurité en cassant l’éditeur.
  • Les flux de nonce et de cookies ont évolué avec des améliorations de la sécurité admin, ce qui signifie que les anciens reverse proxies et configurations SSO peuvent se retrouver incompatibles.
  • Beaucoup de plugins d’optimisation étaient conçus pour le front-end ; ils minifient et diffèrent volontiers les scripts dans wp-admin à moins d’être explicitement configurés pour ne pas le faire.
  • Les thèmes de blocs et l’édition complète du site ont élargi la surface d’éditeur (éditeur de site, parties de templates, styles globaux). Plus d’endpoints. Plus de façons d’échouer.

Premières observations : classer la panne en 60 secondes

Que voit l’utilisateur ?

  • Spinner infini / « Loading… » pour toujours : généralement appel REST bloqué, ou erreur runtime JS tôt dans le bootstrap.
  • Écran blanc / zone de contenu vide : erreur JS fatale, blocage CSP, script 404, ou fatal PHP qui renvoie du HTML dans les endpoints JSON.
  • « The editor has encountered an unexpected error » avec un bouton « Copy error » : c’est bien ; cela signifie que Gutenberg a intercepté quelque chose. Copiez-le et utilisez-le.
  • L’éditeur se charge mais ne peut pas sauvegarder / mettre à jour : souvent problèmes de nonce/auth/cookie, REST 401/403, ou blocage POST par mod_security/WAF.
  • Ça n’arrive qu’à certains utilisateurs : incompatibilité de rôle/capacité, corruption de usermeta, extension de navigateur, ou cookies CDN différents selon les groupes d’utilisateurs.
  • Ça n’arrive que sur un seul article : balisage de bloc malformé, post_content énorme, HTML/shortcodes embarqués qui provoquent le parseur, ou bloat de meta révisions.

Vérifications rapides « est-ce votre machine ? »

  • Essayez en fenêtre privée/incognito.
  • Essayez un autre navigateur.
  • Désactivez les extensions du navigateur (surtout les bloqueurs de pub et de scripts).

Si cela corrige le problème, ce n’est pas un bug WordPress. C’est un sabotage côté client.

Tâches pratiques avec commandes (et décisions)

Ces tâches supposent que vous avez accès shell au serveur (ou au conteneur) hébergeant WordPress. Si vous ne l’avez pas, vous pouvez faire certaines vérifications via le navigateur et l’admin WordPress, mais votre vitesse sera limitée par les réunions.

Task 1: Confirm WordPress and plugin versions via WP-CLI

cr0x@server:~$ cd /var/www/html
cr0x@server:/var/www/html$ wp core version
6.6.2
cr0x@server:/var/www/html$ wp plugin list --status=active --fields=name,version
akismet 5.3.3
wp-super-cache 1.12.4
wordfence 7.11.8

Ce que cela signifie : Vous établissez la base. Le comportement de Gutenberg dépend des versions du core et des plugins.

Décision : Si le core est très ancien (ou les plugins le sont), priorisez la mise à jour en staging. Si vous ne pouvez pas mettre à jour, vous déboguerez autour de bugs connus corrigés ailleurs.

Task 2: Check if REST API is reachable from the server

cr0x@server:~$ curl -sS -D- -o /dev/null https://example.com/wp-json/
HTTP/2 200
content-type: application/json; charset=UTF-8
cache-control: no-cache, must-revalidate, max-age=0

Ce que cela signifie : 200 et content-type JSON est le chemin heureux.

Décision : Si vous obtenez 301/302 en boucle, corrigez site URL ou les en-têtes proxy. Si content-type est text/html, quelque chose intercepte l’endpoint (output d’un thème/plugin, page de blocage du WAF, ou fatal PHP qui dump du HTML).

Task 3: Look for REST responses that are actually HTML (classic Gutenberg killer)

cr0x@server:~$ curl -sS https://example.com/wp-json/ | head
{"name":"Example Site","description":"","url":"https:\/\/example.com","home":"https:\/\/example.com","gmt_offset":"0","timezone_string":"UTC"

Ce que cela signifie : Le JSON commence par {. S’il commence par <!doctype html> ou <html, vous n’obtenez pas du JSON.

Décision : Si du HTML apparaît, vérifiez les plugins de sécurité injectant de la sortie, les erreurs serveur, ou un upstream (CDN/WAF) servant une page de blocage.

Task 4: Verify wp-admin scripts are served correctly (status, type, size)

cr0x@server:~$ curl -sS -D- -o /dev/null "https://example.com/wp-admin/load-scripts.php?c=0&load[]=wp-blocks,wp-element,wp-editor"
HTTP/2 200
content-type: application/javascript; charset=UTF-8
cache-control: private, max-age=0, no-store, no-cache, must-revalidate

Ce que cela signifie : Les scripts de l’éditeur doivent revenir en JavaScript, pas en HTML et pas une « page de challenge » mise en cache.

Décision : Si le content-type est incorrect, arrêtez. Corrigez la réécriture du CDN/minification avant de toucher WordPress.

Task 5: Check for PHP fatals around the time the editor fails

cr0x@server:~$ sudo tail -n 80 /var/log/php8.2-fpm.log
[27-Dec-2025 10:41:12] WARNING: [pool www] child 2314 said into stderr: "PHP Warning:  Undefined array key "foo" in /var/www/html/wp-content/plugins/some-plugin/plugin.php on line 91"
[27-Dec-2025 10:41:12] WARNING: [pool www] child 2314 said into stderr: "PHP Fatal error:  Uncaught Error: Call to undefined function wp_get_environment_type() in /var/www/html/wp-content/plugins/some-plugin/plugin.php:132"

Ce que cela signifie : Les erreurs fatales peuvent casser les réponses REST et les chargeurs de scripts, provoquant indirectement l’échec de Gutenberg.

Décision : Si vous voyez des fatals, désactivez le plugin/thème qui les cause. Ne « contournez » pas les fatals.

Task 6: Check WordPress debug log for REST/editor hints

cr0x@server:~$ sudo tail -n 80 /var/www/html/wp-content/debug.log
[27-Dec-2025 10:41:11 UTC] WordPress database error Deadlock found when trying to get lock; try restarting transaction for query UPDATE `wp_options` SET `option_value` = '...' WHERE `option_name` = '_transient_timeout_wp_core_block_patterns'
[27-Dec-2025 10:41:12 UTC] PHP Warning:  Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/plugins/some-plugin/plugin.php:91)

Ce que cela signifie : Les deadlocks et « headers already sent » se traduisent fréquemment par du JSON cassé.

Décision : Corrigez la contention DB (ou retirez le code provoquant des mises à jour répétées d’options). Corrigez « headers already sent » en supprimant les sorties intempestives, BOMs ou plugins bruyants.

Task 7: Disable all plugins quickly (then re-enable in batches)

cr0x@server:~$ cd /var/www/html
cr0x@server:/var/www/html$ wp plugin deactivate --all
Success: Deactivated 27 of 27 plugins.

Ce que cela signifie : Vous venez de réduire drastiquement l’espace de recherche du problème.

Décision : Si Gutenberg se charge maintenant, réactivez les plugins par groupes de 3–5 jusqu’à ce que ça casse. Le dernier lot contient votre coupable.

Task 8: Switch to a default theme to remove theme-layer editor customizations

cr0x@server:~$ cd /var/www/html
cr0x@server:/var/www/html$ wp theme list --status=active
+----------------+----------+-----------+---------+
| name           | status   | update    | version |
+----------------+----------+-----------+---------+
| corp-theme     | active   | none      | 4.9.1   |
+----------------+----------+-----------+---------+
cr0x@server:/var/www/html$ wp theme activate twentytwentyfour
Success: Switched to 'Twenty Twenty-Four' theme.

Ce que cela signifie : Beaucoup de « thèmes d’entreprise » ajoutent des scripts admin/éditeur, des styles de blocs ou des entêtes CSP.

Décision : Si le thème par défaut corrige, comparez ce que fait le thème dans functions.php : scripts enqueued, filtres REST, entêtes de sécurité et hooks d’éditeur.

Task 9: Validate HTTP status patterns in web server logs (REST endpoints and admin scripts)

cr0x@server:~$ sudo awk '$7 ~ /wp-json|load-scripts.php|admin-ajax.php/ {print $4, $7, $9}' /var/log/nginx/access.log | tail -n 20
[27/Dec/2025:10:41:10 /wp-json/wp/v2/types?context=edit 403
[27/Dec/2025:10:41:10 /wp-admin/load-scripts.php?c=0&load[]=wp-blocks,wp-element,wp-editor 200
[27/Dec/2025:10:41:11 /wp-json/wp/v2/settings 403
[27/Dec/2025:10:41:12 /wp-json/wp/v2/users/me?context=edit 403

Ce que cela signifie : Des 403 répétés sur /wp-json/wp/v2/* suggèrent fortement un WAF/plugin de sécurité ou une mauvaise configuration des capacités.

Décision : Si des 403 correspondent aux chargements d’éditeur, concentrez-vous sur l’auth, les nonces et les règles de sécurité — pas les bundles JS.

Task 10: Check whether your reverse proxy is sending the right scheme/host (common nonce/cookie breakage)

cr0x@server:~$ sudo grep -R "fastcgi_param\|proxy_set_header" -n /etc/nginx/sites-enabled | head -n 40
/etc/nginx/sites-enabled/example.conf:42:proxy_set_header Host $host;
/etc/nginx/sites-enabled/example.conf:43:proxy_set_header X-Forwarded-Proto $scheme;
/etc/nginx/sites-enabled/example.conf:44:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Ce que cela signifie : Si WordPress pense être en HTTP alors que les utilisateurs sont en HTTPS, vous obtenez des cookies mixtes, des redirections incorrectes et des échecs de validation de nonce.

Décision : Si vous êtes derrière un load balancer/ingress, confirmez que X-Forwarded-Proto et WordPress siteurl/home correspondent à la réalité.

Task 11: Check PHP-FPM saturation (latency makes “loading forever” look like a JS problem)

cr0x@server:~$ sudo systemctl status php8.2-fpm --no-pager
● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
     Loaded: loaded (/lib/systemd/system/php8.2-fpm.service; enabled)
     Active: active (running) since Fri 2025-12-27 08:12:04 UTC; 2h 31min ago
     Status: "Processes active: 42, idle: 0, Requests: 19832, slow: 117"

Ce que cela signifie : « idle: 0 » et un compteur de requêtes lentes en hausse indiquent une saturation. Gutenberg déclenche beaucoup de requêtes admin ; il amplifie les goulots.

Décision : Si saturé, inspectez les slow logs, augmentez prudemment les enfants FPM et traitez les causes racines (DB lente, disque lent, plugins lourds) avant d’ajouter des workers qui consumeront la RAM.

Task 12: Check disk space and inode pressure (boring problems cause exciting outages)

cr0x@server:~$ df -h /var/www/html
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  100G   96G  4.0G  96% /
cr0x@server:~$ df -i /var/www/html
Filesystem       Inodes  IUsed   IFree IUse% Mounted on
/dev/nvme0n1p2  6553600 6501021 52579   99% /

Ce que cela signifie : Disques presque pleins ou exhaustion d’inodes peuvent casser les mises à jour de plugins, écritures de cache, fichiers de session et fichiers temporaires utilisés par PHP.

Décision : Si >90% d’utilisation ou inodes >95%, traitez cela comme un incident prioritaire : libérez de l’espace, faites la rotation des logs, purgez les caches et corrigez la croissance.

Task 13: Test database responsiveness and check for table lock pain

cr0x@server:~$ mysql -u root -p -e "SHOW FULL PROCESSLIST\G" | sed -n '1,80p'
*************************** 1. row ***************************
     Id: 1432
   User: wpuser
   Host: 127.0.0.1:59314
     db: wordpress
Command: Query
   Time: 18
  State: Sending data
   Info: SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'

Ce que cela signifie : Les requêtes longues sur wp_options (autoload) sont un vecteur classique de lenteur admin. Gutenberg semblera « cassé » quand il se contente de timeouter.

Décision : Si la requête d’autoload est lente, auditez la taille des options autoload, retirez le superflu et corrigez les plugins qui spamment les options.

Task 14: Check autoloaded options size (the invisible anchor)

cr0x@server:~$ mysql -u root -p wordpress -e "SELECT ROUND(SUM(LENGTH(option_value))/1024/1024,2) AS autoload_mb FROM wp_options WHERE autoload='yes';"
autoload_mb
12.47

Ce que cela signifie : Les options autoload sont chargées à chaque requête. Des mégaoctets sont une taxe de latence, pas « acceptable ».

Décision : Si l’autoload est volumineux, identifiez les principaux coupables et désactivez/optimisez les plugins qui ajoutent de grosses entrées autoload.

Task 15: Identify the biggest autoloaded options (find the plugin doing it)

cr0x@server:~$ mysql -u root -p wordpress -e "SELECT option_name, ROUND(LENGTH(option_value)/1024,1) AS kb FROM wp_options WHERE autoload='yes' ORDER BY LENGTH(option_value) DESC LIMIT 15;"
option_name	kb
some_plugin_cache	2048.0
theme_mods_corp-theme	1536.4
wpseo_titles	412.7

Ce que cela signifie : Vous avez maintenant des noms. Les noms sont exploitables.

Décision : Pour les grosses options de cache de plugin, passez-les en non-autoload ou purgez-les. Pour les theme_mods, regardez si le thème stocke trop et si l’éditeur de site amplifie cela.

Task 16: Temporarily bypass object cache to see if Redis/Memcached is poisoning admin

cr0x@server:~$ cd /var/www/html/wp-content
cr0x@server:/var/www/html/wp-content$ ls -l object-cache.php
-rw-r--r-- 1 www-data www-data  48210 Dec 10 09:14 object-cache.php
cr0x@server:/var/www/html/wp-content$ sudo mv object-cache.php object-cache.php.disabled

Ce que cela signifie : WordPress utilise wp-content/object-cache.php comme drop-in. Renommer le fichier le désactive.

Décision : Si Gutenberg fonctionne après désactivation du cache d’objets, votre backend de cache ou le drop-in est buggy/mal configuré. Corrigez-le ; ne laissez pas le cache désactivé en permanence sauf si vous aimez les factures DB élevées.

Task 17: Confirm headers aren’t blocking scripts (CSP is a frequent self-own)

cr0x@server:~$ curl -sS -D- -o /dev/null https://example.com/wp-admin/post-new.php | egrep -i "content-security-policy|x-frame-options|x-content-type-options"
content-security-policy: default-src 'self'; script-src 'self'; object-src 'none'
x-content-type-options: nosniff

Ce que cela signifie : Un script-src 'self' strict peut casser wp-admin parce que le core repose parfois sur des scripts inline (et des chunks chargés dynamiquement).

Décision : Si la CSP est stricte, ajustez-la spécifiquement pour wp-admin (ou retirez-la là‑bas). La sécurité est bonne ; casser votre éditeur n’est pas « sécurisé », c’est juste gênant.

Task 18: Check for mixed content or forced HTTP in WordPress config

cr0x@server:~$ wp option get siteurl
https://example.com
cr0x@server:~$ wp option get home
https://example.com

Ce que cela signifie : Si ceux-ci sont en HTTP alors que votre admin est en HTTPS, vous aurez des mismatches d’assets et des comportements bizarres de cookies.

Décision : Corrigez siteurl/home et les en-têtes proxy. Puis videz les caches.

Erreurs courantes : symptôme → cause racine → correctif

1) Symptom: Infinite “Loading…” spinner in the editor

Cause racine : Appels REST retournant 403 (WAF/plugin de sécurité) ou renvoyant du HTML au lieu du JSON.

Correctif : Vérifiez /wp-json/ et /wp-json/wp/v2/users/me?context=edit dans DevTools Network. Mettez les endpoints REST en liste blanche dans le WAF, adaptez les règles du plugin de sécurité ou corrigez les fatals PHP produisant du HTML.

2) Symptom: “The editor has encountered an unexpected error” after a plugin update

Cause racine : Un plugin enfile des scripts dans wp-admin incorrectement (mauvaises dépendances, React conflit, ou écrasement de variables globales).

Correctif : Désactivez le plugin. Si vous devez le garder, assurez-vous qu’il n’embarque pas sa propre version de React ou ne bundle pas incorrectement des paquets WordPress ; mettez-le à jour vers une version compatible.

3) Symptom: Editor works for admins, fails for editors/authors

Cause racine : Restrictions de capacités/rôles bloquant les endpoints REST avec context=edit, souvent via plugins d’adhésion ou du code personnalisé.

Correctif : Comparez les réponses REST selon les rôles. Corrigez le mapping des capacités et ne bloquez pas globalement les endpoints wp/v2.

4) Symptom: Editor loads only in incognito

Cause racine : Extensions du navigateur, assets mis en cache erronés, ou interférence de service worker.

Correctif : Désactivez les extensions, effacez les données du site et assurez-vous que les assets admin ne sont pas mis en cache par le CDN. Vérifiez que cache-control sur load-scripts.php est privé/no-store.

5) Symptom: “Updating failed. The response is not a valid JSON response.”

Cause racine : L’appel REST de sauvegarde renvoie du HTML (output d’un warning PHP, page de blocage WAF, ou page d’erreur 500).

Correctif : Regardez le corps de la requête réseau échouée. Corrigez le warning/fatal PHP, désactivez le plugin qui imprime de la sortie, ou mettez l’endpoint en liste blanche dans le WAF.

6) Symptom: Gutenberg only breaks on big posts

Cause racine : post_content énorme, nombreux blocs, shortcodes lourds, ou exhaustion mémoire lors du parse/render du markup de blocs.

Correctif : Augmentez la mémoire PHP et le temps d’exécution prudemment, retirez les blocs/shortcodes pathologiques, scindez le contenu et nettoyez les révisions.

7) Symptom: Editor broken right after “performance optimization”

Cause racine : Plugin de minification/différation appliqué à wp-admin, ou CDN qui met en cache wp-admin/load-scripts.php.

Correctif : Excluez wp-admin et load-scripts.php des optimisations. Assurez-vous que l’edge respecte les en-têtes private/no-store pour l’admin.

8) Symptom: Random failures, especially under load

Cause racine : Saturation PHP-FPM, DB lente, instabilité du cache d’objets, latence disque ou exhaustion d’inodes.

Correctif : Traitez-le comme un incident de performance : vérifiez l’état de FPM, les slow logs, le processlist DB, l’espace disque/inodes. Corrigez la capacité et les points chauds.

Listes de contrôle / plan étape par étape

Checklist A: Debug Gutenberg not loading (15–30 minutes)

  1. Console du navigateur : capturez la première erreur rouge. Pas la dixième. La première a généralement de l’importance.
  2. Onglet Réseau : identifiez la première requête échouée (souvent /wp-json/, /wp-json/wp/v2/settings ou /wp-admin/load-scripts.php).
  3. Confirmer côté serveur : curl de l’endpoint échoué et vérification du statut et du content-type.
  4. Désactiver les plugins : wp plugin deactivate --all.
  5. Changer de thème : activez temporairement un thème par défaut.
  6. Contourner les caches : désactivez le drop-in de cache d’objets ; contournez le CDN si possible (host header direct d’origine ou route VIP interne).
  7. Vérifier les logs : log PHP-FPM + log d’erreur web + WordPress debug log.
  8. Restaurer progressivement : réactivez les plugins par lots, puis le thème, puis les caches.

Checklist B: When saving fails but editor loads

  1. Dans DevTools, trouvez la requête de sauvegarde échouée (souvent POST vers /wp-json/wp/v2/posts/ID).
  2. Inspectez le corps de la réponse : est‑il HTML (page d’erreur), JSON (avec code d’erreur) ou vide ?
  3. Vérifiez les en-têtes d’auth : l’utilisateur est-il connecté ? Y a‑t‑il un SSO ou un reverse proxy réécrivant les cookies ?
  4. Consultez les logs serveur pour 401/403/500 au moment de la requête.
  5. Désactivez temporairement les règles WAF affectant les endpoints POST/JSON.
  6. Confirmez que la génération de nonce n’est pas mise en cache (les pages admin ne doivent pas être cachées).

Checklist C: Performance-induced “won’t load” (because timeouts look like bugs)

  1. Vérifiez l’état PHP-FPM active/idle, les requêtes lentes et les timeouts.
  2. Vérifiez la DB : requêtes longues, verrous de table et taille d’autoload.
  3. Vérifiez le disque : espace, inodes et symptômes de latence I/O (queue depth, await élevé).
  4. Désactivez d’abord les plugins admin les plus lourds (page builders, tableaux de bord analytics, scanners de sécurité).
  5. Puis seulement, ajustez les timeouts/mémoire. Augmenter les limites sans corriger la lenteur prolonge juste la souffrance.

Blague n°2 : Quand quelqu’un dit « Je n’ai rien changé », je suppose qu’il veut dire « J’ai changé quelque chose et je ne l’ai pas noté ».

Trois mini-récits d’entreprise depuis le terrain

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Une entreprise de taille moyenne faisait tourner WordPress derrière un load balancer et un reverse proxy nginx. La migration a été « simple » : déplacer le trafic, garder l’origine identique, considérer la tâche comme réussie. L’éditeur a immédiatement commencé à bloquer pour certains utilisateurs, mais pas tous. Naturellement, la première théorie a été « Gutenberg est instable ».

L’indice était dans la trace réseau : les appels REST vers /wp-json/wp/v2/users/me?context=edit renvoyaient 401 pour certaines sessions. Même utilisateur, résultats différents selon le nœud du proxy. Ça sentait les cookies.

Ils ont supposé que l’app inférerait HTTPS correctement parce que « le load balancer termine le TLS ». WordPress se fichait de cette supposition. WordPress regardait ce qu’il voyait : des requêtes arrivant à l’origine en HTTP, et WordPress générait cookies/nonces avec un comportement décalé par rapport à la réalité HTTPS du navigateur.

La correction n’a rien de mystique. Ils ont correctement défini X-Forwarded-Proto, fait en sorte que WordPress le respecte et corrigé siteurl/home. L’éditeur a récupéré instantanément, et le post‑mortem était ennuyeusement ordinaire : le système a fait exactement ce pour quoi il était configuré, pas ce que les gens croyaient.

Mini-récit 2 : L’optimisation qui a mal tourné

Une autre organisation souhaitait accélérer l’admin et a déployé une règle de « cache intelligent » au niveau du CDN : cacher toute requête avec 200 et des paramètres de query « statiques ». Quelqu’un a remarqué que load-scripts.php et load-styles.php ressemblaient à des assets statiques. Ils se sont trompés de la manière qui casse les lundis matin.

Pendant un temps, tout semblait bien. Puis une mise à jour mineure de WordPress est arrivée. Le bundle de scripts admin mis en cache ne correspondait plus aux attentes serveur, et soudain Gutenberg a commencé à échouer avec des erreurs JS référant des modules manquants et des fonctions undefined.

Les ingénieurs ont couru après des fantômes : conflits de plugins, problèmes de thème, bugs de navigateur. L’indice était que l’erreur n’apparaissait que pour les utilisateurs servis par le cache edge du CDN, et disparaissait en contournant l’edge. Les en-têtes de réponse mises en cache étaient aussi suspectes : « public ».

La correction : ne jamais mettre en cache les load-scripts.php de wp-admin au CDN, respecter les en-têtes private/no-store de WordPress et ne pas traiter des assets avec query-string comme sûrs seulement parce qu’ils y ressemblent. L’« optimisation » a été annulée et l’admin est redevenu ennuyeux — ce qui est la bonne performance pour un backend CMS.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Un site d’entreprise avait une règle opérationnelle : tout changement touchant le cache, le WAF ou les en-têtes proxy devait inclure un test préliminaire sur trois endpoints — /wp-json/, /wp-admin/load-scripts.php, et un appel REST authentifié. Pas glamour. Obligatoire.

Un après-midi, l’équipe sécurité a poussé une nouvelle politique WAF pour réduire le trafic bot. Elle bloquait des requêtes ressemblant à de « l’énumération d’API », ce qui incluait certaines routes REST utilisées par des écrans admin authentifiés. L’équipe CMS ne l’a pas remarqué tout de suite car les pages front‑end rendaient toujours.

Mais le test pré‑vol, exécuté par un job CI avec un compte éditeur à faible privilège, a échoué en quelques minutes. Le rapport d’erreur contenait les codes HTTP et des extraits de réponses. L’équipe CMS n’a pas eu à débattre pour savoir si Gutenberg était « down » ; ils avaient des preuves.

La politique WAF a été ajustée avec une règle allow ciblée pour le trafic wp-json authentifié, et l’incident est resté mineur. La morale est prévisible : les vérifications ennuyeuses que vous automatisez sont celles qui vous sauvent quand les humains deviennent créatifs.

FAQ

1) Pourquoi Gutenberg dépend-il autant de l’API REST ?

Parce que c’est une application JavaScript qui récupère et sauvegarde le contenu via des routes API. Si /wp-json/ est bloqué, Gutenberg ne peut pas charger les données de l’article, les réglages, les infos utilisateur ou les opérations de sauvegarde de manière fiable.

2) L’éditeur fonctionne sur mon portable mais pas pour des collègues. Qui suspecter en premier ?

Les couches de cache et de sécurité qui varient selon la géographie, le cookie ou l’IP. Le comportement du CDN edge, les challenges WAF ou les proxies d’entreprise peuvent casser sélectivement les requêtes wp-admin.

3) Un seul warning PHP peut-il vraiment casser l’éditeur ?

Oui. Si un warning imprime de la sortie pendant une réponse REST, votre JSON devient « JSON plus bruit », et Gutenberg le traite comme invalide. Corrigez le warning ou supprimez proprement la sortie — ne la cachez pas simplement.

4) Dois‑je simplement installer le plugin Classic Editor et passer à autre chose ?

Seulement comme mitigation temporaire. Cela peut maintenir les éditeurs opérationnels pendant que vous réglez le problème REST/cache/sécurité sous‑jacent. Si vous en faites la solution permanente, vous payez des intérêts sur un problème.

5) Quelle est la manière la plus rapide de prouver qu’il s’agit d’un conflit de plugin ?

Désactivez tous les plugins via WP-CLI et retestez. Si ça fonctionne, réactivez par lots. C’est plus rapide que lire le code des plugins en prétendant que cela vous plaît.

6) Ma base de données peut-elle être la raison pour laquelle Gutenberg ne se charge pas ?

Absolument. Options autoload lentes, deadlocks ou requêtes longues peuvent retarder les réponses REST jusqu’à ce que l’UI expire ou paraisse figée. Vérifiez le processlist et la taille de l’autoload.

7) Le cache d’objets aide ou nuit à Gutenberg ?

Les deux. Un cache d’objets bien configuré réduit la charge DB et accélère l’admin. Des drop-ins buggy ou mal configurés peuvent renvoyer des données obsolètes/incorrectes, casser des nonces ou produire un comportement incohérent. Désactivez temporairement pour isoler.

8) Je reçois des 403 sur les routes wp-json seulement dans wp-admin. Pourquoi ?

Parce que les appels REST authentifiés incluent des cookies et des nonces, et les couches de sécurité les traitent souvent différemment. Des règles WAF acceptables pour des GET anonymes peuvent bloquer des routes API authentifiées utilisées par l’éditeur.

9) La CSP dans wp-admin est‑elle une mauvaise idée ?

Pas forcément, mais elle est facile à mal configurer. Si vous définissez une politique stricte sans tenir compte des patterns de scripts de l’admin WordPress, vous bloquerez des fonctionnalités core. Appliquez la CSP avec précaution et testez l’éditeur.

10) Mon site est en multisite. Des modes de panne Gutenberg spécifiques ?

Oui : problèmes de mapping de domaine, étendue des cookies sur les sous‑domaines, et plugins activés en réseau affectant le comportement REST. Testez l’API REST et l’éditeur sur plusieurs sous‑sites et rôles.

Prochaines étapes à faire aujourd’hui

  1. Prouvez la couche : console du navigateur + onglet réseau, puis curl des mêmes endpoints depuis le serveur.
  2. Rendez l’API REST banale : assurez-vous que /wp-json/ renvoie du JSON avec 200, pas de redirections, pas de HTML, pas de théâtre WAF.
  3. Isolez les variables : désactivez les plugins, passez à un thème par défaut, contournez le cache d’objets, contournez CDN/WAF.
  4. Corrigez les problèmes d’infrastructure ennuyeux : saturation PHP-FPM, pression disque, bloat autoload DB et en-têtes proxy mal réglés.
  5. Verrouillez la prévention : ajoutez un contrôle automatisé simple qui frappe les endpoints REST et les scripts admin après tout changement de cache/WAF/proxy.

Si vous faites ces étapes dans cet ordre, vous cesserez de « déboguer Gutenberg » et commencerez à réparer le système réel que Gutenberg se contente de révéler. Et c’est tout le jeu.

← Précédent
Pilotes non signés : quand la sécurité a cassé du matériel parfaitement fonctionnel
Suivant →
Ubuntu 24.04 « Instruction illégale » : drapeaux CPU vs binaires — corriger proprement les déploiements (cas n°56)

Laisser un commentaire