Migrer un vieux forum phpBB : l’erreur qui m’a coûté 3 mois d’indexation

En 15 ans à réparer des sites de PME, je pensais avoir vu toutes les variantes de la même erreur : casser des URLs sans redirections. Puis un client de Nantes m’a confié un vieux forum phpBB, et j’ai réussi à commettre une variante que je n’avais pas anticipée. Ce texte est un compte-rendu honnête d’un raté, pas une success story déguisée.

Le contexte : un forum phpBB de 2006 encore vivant en 2023

Le client fabriquait du matériel d’aquariophilie et animait, depuis 2006, un forum communautaire phpBB sur un sous-domaine. Rien d’exceptionnel dans le principe : forum.entreprise-x.fr, structure classique en viewtopic.php?f=12&t=4381, plus de 38 000 sujets, une communauté de passionnés encore active avec 40 à 60 posts par jour. Le genre de forum qu’on croit mort en le regardant, mais qui génère en réalité 22% du trafic organique du site principal, essentiellement sur des requêtes longue traîne du type « pH trop bas aquarium eau douce que faire ».

Le mandat initial était simple : le forum tournait sur PHP 5.6, hébergé sur un serveur mutualisé qui n’était plus maintenu par personne depuis le départ de l’ancien webmaster. Il fallait le sortir de là avant la fin de vie annoncée du serveur. Migration technique, pas refonte de contenu. Sur le papier, un chantier de trois semaines.

L’erreur : j’ai sous-traité la question des URLs à l’outil de migration

Voici le cœur du raté, et je préfère le dire sans détour : j’ai utilisé un plugin de migration phpBB vers WordPress (avec un plugin forum type bbPress) en me fiant à sa documentation qui promettait une « migration complète avec préservation SEO ». J’ai testé l’import sur un environnement de staging, vérifié que les 38 000 sujets étaient bien présents, vérifié que les auteurs et les dates étaient corrects, vérifié que le rendu visuel tenait la route. J’ai validé.

Ce que je n’ai pas vérifié assez tôt : la structure des nouvelles URLs. Le plugin générait des slugs à partir du titre du sujet, avec troncature à 60 caractères et une gestion des doublons par suffixe numérique. Résultat concret : /forum/viewtopic.php?f=12&t=4381 devenait /communaute/ph-trop-bas-aquarium-eau-douce-que-faire-2/. Un slug différent, sur un chemin différent, sans aucun lien technique entre l’ancienne et la nouvelle adresse.

Le plugin proposait bien une option « générer les redirections 301 », que j’ai cochée. Le problème, découvert trop tard, est qu’elle ne fonctionnait que pour les identifiats de sujet stockés dans un format précis (t= suivi d’un entier isolé en fin de chaîne). Or une partie non négligeable des liens externes et internes vers ce forum utilisait des variantes historiques : liens avec ancre de pagination (&start=15), liens vers un post précis via ancre (#p28456), liens générés par un ancien plugin SEO du forum qui réécrivait déjà les URLs en 2014. Trois formats d’URLs différents pointant vers le même contenu, accumulés sur seize ans d’évolutions techniques successives. Le générateur de redirections n’en couvrait qu’un seul correctement.

Je n’ai pas fait l’inventaire de ces variantes avant la bascule. J’ai fait confiance à l’outil parce que le test sur un échantillon de 50 URLs avait fonctionné. Cinquante URLs sur trente-huit mille, c’est 0,13% de l’échantillon réel. Ce chiffre-là, je le regrette encore.

Les conséquences : chute de trafic et perte de confiance côté client

La bascule a eu lieu un vendredi soir, horaire creux, comme il se doit. Le lundi, rien d’alarmant en apparence. Le vrai signal est arrivé douze jours plus tard, quand Google Search Console a commencé à faire remonter des erreurs 404 en masse sur le nouveau sous-répertoire. En trois semaines, plus de 6 200 URLs de l’ancien forum étaient recensées en « introuvable (404) » dans le rapport de couverture. Le trafic organique global du site a baissé de 40% par rapport à la moyenne des huit semaines précédentes, avec un plancher atteint six semaines après la bascule.

Ce n’était pas qu’une perte de trafic abstraite. C’était des utilisateurs qui arrivaient depuis un lien Pinterest ou un forum tiers datant de 2018, atterrissaient sur une page 404 générique, et repartaient. C’était aussi, plus grave à moyen terme, une perte de confiance de la communauté elle-même : les membres actifs partageaient encore leurs anciens sujets par lien direct dans d’autres forums et groupes Facebook. Une bonne partie de ces liens, historiques et donc à forte autorité, sont morts d’un coup.

Le client, à raison, m’a demandé des comptes. Je n’ai pas cherché à minimiser : j’ai partagé le rapport GSC brut, expliqué la cause technique exacte, et proposé un plan de correction chiffré avec délai. C’est ce genre de moment qui fait la différence entre un prestataire qu’on garde et un qu’on vire — l’honnêteté immédiate compte plus que la perfection qu’on n’a pas eue.

La correction : cartographie manuelle et redirections par lot

La première action, dans les 24 heures suivant la détection du problème, a été de récupérer un dump complet de la base MySQL de l’ancien forum, encore accessible en lecture seule sur le serveur d’origine que je n’avais heureusement pas encore résilié. Sans cette base, aucune correction n’aurait été possible dans un délai raisonnable — c’est la première leçon opérationnelle : ne jamais couper l’accès à la source tant que la totalité des redirections n’est pas validée en production, pas seulement en staging.

À partir de ce dump, j’ai reconstruit la table de correspondance topic_id → nouveau slug avec un script PHP indépendant du plugin, en couvrant cette fois les trois formats d’URLs historiques identifiés dans les logs serveur des deux années précédentes (Apache conservait les logs sur 24 mois, ce qui a été une chance). Le script a produit 41 800 lignes de correspondance, contre les 6 100 générées automatiquement par le plugin au départ — l’écart mesure précisément l’ampleur du trou initial.

Ces correspondances ont été injectées sous forme de règles Nginx via une table de correspondance externe (map chargée depuis un fichier généré, pas 41 800 lignes de rewrite en dur dans le vhost, qui aurait rendu le fichier ingérable et ralenti chaque requête). Après déploiement et purge cache, j’ai soumis un fichier de désindexation/réindexation dans Search Console pour les URLs les plus consultées historiquement, et laissé le reste au crawl naturel de Google guidé par les 301.

Le trafic a commencé à remonter environ cinq semaines après la mise en place des redirections corrigées, et il a fallu près de trois mois complets pour retrouver 90% du niveau d’avant migration. Les 10% restants ne sont, à ce jour, jamais revenus — une partie des liens externes cassés pendant la fenêtre de 404 ont été retirés par leurs auteurs plutôt que corrigés, et ce trafic-là est perdu de façon définitive.

Ce que je fais différemment aujourd’hui

Trois changements concrets dans ma méthode depuis cet épisode :

  • Avant toute migration de forum ou de CMS avec plus de 1 000 URLs indexées, j’exporte systématiquement la liste complète des URLs connues de Google via Search Console (export Performance, 16 mois, toutes les pages avec au moins une impression) et je la croise avec le crawl du site en cours. Un échantillon de 50 URLs ne dit rien sur un corpus de 38 000.
  • Je ne fais plus jamais confiance à une fonctionnalité « préservation SEO automatique » d’un plugin sans lire son code de génération de redirections. Dans ce cas précis, une lecture de 20 minutes du fichier PHP concerné m’aurait montré la regex limitée à un seul format d’URL, avant la bascule et non trois semaines après.
  • Je conserve désormais l’accès en lecture au système source pendant un minimum de 90 jours après toute migration, quel que soit le coût d’hébergement résiduel — c’est une ligne budgétaire que j’inclus systématiquement dans le devis, environ 15 à 30 euros par mois selon l’hébergeur, negligeable face au coût d’une correction à l’aveugle.

La limite honnête de cette méthode : elle suppose qu’on a accès aux logs serveur historiques et au dump de base d’origine. Sur un forum hébergé chez un tiers qui refuse l’accès, ou dont la base a déjà été supprimée, cette reconstruction n’est simplement pas possible, et il faut le dire au client avant de signer, pas après.

La leçon durable

Un vieux forum phpBB ou vBulletin avec des URLs en viewtopic.php n’est jamais un sujet purement technique. C’est un corpus SEO accumulé sur quinze ou vingt ans, avec des formats d’URLs hétérogènes qui reflètent l’histoire des plugins et des refontes successives du forum lui-même. Traiter ça comme une migration de contenu standard, avec un outil générique et un échantillon de test trop petit, c’est le raté que j’ai fait une fois et que je ne referai plus. La règle que j’applique maintenant sur tout site avec un historique de plus de dix ans : le nombre d’heures passées à cartographier les anciennes URLs doit être proportionnel à l’ancienneté du site, pas à la taille apparente du projet.