Migrer de WordPress vers un CMS headless sans perdre de trafic
Un export WXR, un modèle de contenu qui ne correspond pas, et une logique d'extension qui ne se transfère pas. Le parcours de migration étape par étape — y compris ce qui casse.
Si vous hésitez encore sur le fait de savoir s'il faut migrer, lisez d'abord corpusctl vs WordPress — il défend, honnêtement, l'idée que la plupart des sites WordPress devraient rester en place.
Cet article suppose que la décision est prise. Il porte sur la façon de le faire sans vous réveiller devant une courbe de trafic en forme de falaise.
Faites cela avant toute autre chose, car c'est là que les migrations trouvent leur véritable budget.
Parcourez la liste des extensions et rangez chacune dans l'une de trois catégories :
| Catégorie | Exemple | Migre-t-elle ? |
|---|---|---|
| Stocke du contenu | Advanced Custom Fields, types de publication personnalisés | Oui — c'est dans l'export |
| Transforme du contenu | Shortcodes, constructeurs de pages, blocs d'articles liés | En partie — la sortie est dans le corps, la logique non |
| Fournit un comportement | Formulaires, réservations, adhésions, e-commerce, cache | Non — à reconstruire ou remplacer |
La troisième catégorie, c'est le projet. Une extension de formulaire devient un service de formulaire. Une extension d'adhésion devient de l'authentification plus du verrouillage dans votre interface. Personne n'exporte cela, et c'est la raison pour laquelle les migrations s'éternisent.
La deuxième catégorie comporte un piège spécifique : les constructeurs de pages. Si vos articles sont construits avec Elementor, WPBakery ou similaire, le corps exporté est une soupe de shortcodes et de balisage d'enrobage, pas du HTML propre. Prévoyez de le nettoyer, ou de réécrire à la main les pages concernées. Comptez-les dès maintenant.
Tools → Export → All content produit un fichier WXR : du XML contenant articles, pages, types de publication personnalisés, taxonomies, commentaires et références aux médias.
Des références, pas des fichiers. Les images se trouvent toujours dans wp-content/uploads et doivent être déplacées séparément.
Deux choses à vérifier avant de vous fier au fichier :
wp_posts.L'instinct est d'importer puis de ranger. Faites l'inverse.
Un article WordPress avec huit champs personnalisés correspond généralement à deux ou trois types en bonne et due forme dans un CMS structuré. Décidez de cette forme avant l'import, sinon vous transporterez le modèle de WordPress dans un système que vous avez précisément choisi pour y échapper.
Dans corpusctl, il n'y a pas de types de contenu intégrés ; vous les définissez depuis le panneau ou l'API, et les champs portent des rôles — title, slug, body. Le rôle est la façon dont le système sait quel champ est le titre quel que soit le nom que vous lui avez donné, ce qui permet aux champs calculés comme le temps de lecture et la table des matières de fonctionner sans configuration.
Une correspondance typique :
| WordPress | Devient |
|---|---|
| Titre de l'article | champ avec rôle title |
| Slug de l'article | champ avec rôle slug |
| Contenu de l'article | champ avec rôle body, blocs |
| Image à la une | référence média |
| Catégories, étiquettes | relation de taxonomie, ou un champ tags |
| Auteur | type author distinct avec une relation |
| Groupe de champs ACF | ses propres champs, ou un objet imbriqué |
La localisation est une propriété de champ, pas un site dupliqué. Si vous utilisiez WPML ou Polylang, c'est l'étape où cette structure se simplifie.
Le module d'import de corpusctl lit le WXR et dispose d'un mode à blanc : il produit un plan sans rien écrire.
La réponse contient les entrées qu'il créerait, plus skipped avec une raison pour chacune et warnings. Lisez les deux. C'est par un saut silencieux que vous découvrez au deuxième mois que 400 articles ne sont jamais arrivés.
Les limites d'import existent pour une raison — l'analyseur rejette d'emblée le XML contenant des déclarations DOCTYPE/ENTITY, car c'est le vecteur de la bombe XML, et les fichiers au-delà du plafond de taille sont rejetés plutôt que chargés en flux dans la mémoire. Si votre export déclenche l'un ou l'autre, découpez-le.
Puis lancez-le pour de vrai et rapprochez les décomptes : articles entrés, articles sortis, par type.
C'est la tâche la plus importante et c'est un projet web classique, donc le seul conseil spécifique à la migration concerne les URL.
Préservez la structure des URL si vous le pouvez. Chaque URL que vous conservez est une redirection que vous n'avez pas à écrire et un signal de classement que vous n'avez pas à transférer. Si la structure actuelle est /2019/03/some-post/ et que vous la détestez, la changer est un projet séparé — n'incluez pas une restructuration d'URL dans une migration de CMS. Si les deux tournent mal, vous ne saurez pas laquelle en est la cause.
Côté lecture, le client de corpusctl n'appelle pas d'API : le contenu publié est écrit dans un fichier immuable adressé par hachage au moment de la publication, et le client résout le slug vers un fragment de manifeste en local, puis récupère cette adresse depuis le cache de périphérie nginx. Deux requêtes, toutes deux mises en cache, dont aucune ne touche la base de données.
Les moteurs de rendu de blocs sont livrés avec zéro style par défaut, donc votre travail de design est votre travail de design — le CMS n'apporte aucun CSS avec lequel se disputer.
Chaque ancienne URL a besoin d'une redirection 301 vers son nouvel emplacement. La liste que les gens écrivent :
La liste qu'ils oublient :
/some-post/image-name/) — WordPress en génère une par élément média et Google les a indexées/feed/, /comments/feed/, flux par catégorie/page/2/, /page/3/ …?p=123 et ?page_id=123 sous forme de chaîne de requêteExportez la liste des URL depuis la Search Console (rapport Pages) plutôt que depuis le sitemap. Le sitemap est ce que vous vouliez publier ; la Search Console est ce que Google a réellement trouvé.
Passez en production à une heure de faible trafic, puis surveillez pendant deux semaines :
La Search Console — la Couverture pour un pic de 404 ou de pages « exclues » ; les Performances segmentées par type de page pour voir si un gabarit a perdu plus que les autres.
Les journaux du serveur — le journal d'exploration vous dit ce que Googlebot atteint et ce qu'il obtient. Un 404 dans le journal est une redirection que vous avez manquée, et la corriger le jour même ne coûte rien alors que la corriger dans un mois coûte des positions.
Les Core Web Vitals — les données de terrain, pas les scores de laboratoire. C'est généralement là qu'une migration headless montre une véritable amélioration, parce qu'un contenu pré-construit servi depuis le cache n'a pas d'origine lente à dissimuler.
Ne supprimez pas l'installation WordPress avant au moins un mois. Gardez-la en marche, déliée et noindex, pour pouvoir vérifier à quoi une page ressemblait auparavant.
Les éditeurs se plaindront de l'aperçu. WordPress affiche les aperçus au sein du CMS. L'aperçu headless passe par votre interface via le mode brouillon, et si vous ne l'avez pas câblé avant la bascule, l'équipe éditoriale le remarquera dès le premier jour. Câblez-le en premier. (L'assistant de mode brouillon de corpusctl valide le secret avec une comparaison à temps constant et refuse tout slug qui n'est pas un chemin relatif confirmé, ce qui ferme la faille de redirection ouverte que la plupart des points de terminaison d'aperçu faits maison présentent.)
Les shortcodes laissent des résidus. Tout ce qu'une extension rendait apparaît en texte brut dans le corps importé. Faites un grep du corpus à la recherche de [ après l'import.
Les commentaires. Le WXR les exporte ; la plupart des CMS headless n'ont nulle part où les mettre. Si les commentaires comptent, prévoyez un service tiers avant la bascule, pas après.
Le premier mois est plus lent. Les gens savent où se trouve chaque chose dans WordPress après dix ans. Prévoyez cela dans le budget, et ne programmez pas un lancement la même semaine.
À lire aussi : corpusctl vs WordPress · SEO des CMS headless : par où le trafic fuit · Qu'est-ce qu'un CMS headless ?