Un e-commerce de 18 000 pages migre de Magento 1 vers Shopify. Trois semaines après le go-live, le trafic organique a chuté de 47%. Le diagnostic : 3 200 URLs de catégories et fiches produit renvoyaient un 404 silencieux — les redirections n'avaient couvert que les pages visibles dans le menu principal. Le reste, pages filtrées, anciennes promotions, URLs avec paramètres de tracking, avait été oublié. Le recovery a pris 5 mois.
Ce scénario est évitable. Mais il exige un plan de redirection exhaustif, pas un fichier CSV fait à la main en fin de projet.
Inventaire complet : la fondation que tout le monde bâcle
Le réflexe classique est d'exporter le sitemap XML, de mapper les URLs vers la nouvelle structure, et de considérer le travail fait. C'est précisément là que les migrations échouent. Le sitemap ne contient qu'une fraction des URLs que Google connaît.
Les sources d'URLs à croiser
Votre inventaire doit fusionner au minimum quatre sources :
1. Le crawl complet du site actuel. Screaming Frog en mode Spider, sans limite de profondeur, avec le suivi des paramètres d'URL activé. Configurez-le pour crawler les URLs trouvées dans les sitemaps, les liens internes, et les ressources référencées en JavaScript.
2. Les URLs indexées dans Google Search Console. Le rapport "Pages" > "Indexées" donne la liste des URLs que Google a effectivement dans son index. C'est souvent 20 à 40% de plus que ce que contient votre sitemap, surtout si vous avez des pages à paramètres, des paginations anciennes, ou des URLs générées par des filtres à facettes.
3. Les URLs qui reçoivent des backlinks. Exportez votre profil de liens depuis Ahrefs, Majestic ou Search Console (rapport "Liens" > "Pages les plus liées en externe"). Une URL qui ne génère plus de trafic direct mais qui porte 15 referring domains reste un asset SEO. Si elle renvoie un 404 après migration, vous perdez le jus de ces liens.
4. Les URLs à trafic organique non nul. Google Analytics ou votre outil de web analytics, filtré sur le trafic organique des 12 derniers mois. Toute URL ayant généré au moins une session organique doit être dans le mapping.
Automatiser la fusion et la déduplication
Avec 18 000 pages, la fusion manuelle n'est pas réaliste. Voici un script Python qui fusionne les exports CSV de ces quatre sources et déduplique par URL canonique :
import pandas as pd
from urllib.parse import urlparse, urljoin
# Chargement des sources
crawl = pd.read_csv("screaming_frog_export.csv", usecols=["Address"])
gsc = pd.read_csv("gsc_indexed_pages.csv", usecols=["URL"])
backlinks = pd.read_csv("ahrefs_top_pages.csv", usecols=["URL", "Referring Domains"])
analytics = pd.read_csv("ga_organic_landing_pages.csv", usecols=["Landing Page", "Sessions"])
# Normalisation : tout en minuscules, suppression du trailing slash
def normalize(url: str, base: str = "https://www.monsite.fr") -> str:
parsed = urlparse(url)
if not parsed.scheme:
url = urljoin(base, url)
return url.lower().rstrip("/")
crawl["url"] = crawl["Address"].apply(normalize)
gsc["url"] = gsc["URL"].apply(normalize)
backlinks["url"] = backlinks["URL"].apply(normalize)
analytics["url"] = analytics["Landing Page"].apply(lambda x: normalize(x))
# Fusion
all_urls = set(crawl["url"]) | set(gsc["url"]) | set(backlinks["url"]) | set(analytics["url"])
# Enrichissement avec les métriques
master = pd.DataFrame({"url": list(all_urls)})
master = master.merge(
backlinks[["url", "Referring Domains"]].drop_duplicates("url"),
on="url", how="left"
)
master = master.merge(
analytics[["url", "Sessions"]].rename(columns={"url": "url"}),
on="url", how="left"
)
master.fillna(0, inplace=True)
master.sort_values("Referring Domains", ascending=False, inplace=True)
master.to_csv("migration_url_master_list.csv", index=False)
print(f"Total URLs uniques à mapper : {len(master)}")
Ce script produit un fichier maître trié par nombre de referring domains. Les URLs en haut de liste sont celles où une erreur de redirection coûte le plus cher. Dans le cas de l'e-commerce à 18 000 pages, ce processus a révélé 4 300 URLs supplémentaires absentes du sitemap — dont 800 avec au moins un backlink externe.
Pour les sites avec un crawl budget contraint, cet inventaire exhaustif est doublement critique : chaque 404 rencontrée par Googlebot est un crawl gaspillé qui aurait pu servir à découvrir vos nouvelles pages.
Construction du mapping : règles, patterns et cas limites
Le mapping URL par URL est nécessaire pour les pages stratégiques (top 100 pages par trafic, pages avec le plus de backlinks). Pour le reste, vous avez besoin de règles de réécriture par pattern.
Règles de réécriture par pattern
Sur un site e-commerce qui passe de /categorie/sous-categorie/produit.html à /collections/sous-categorie/produit, la règle Nginx ressemble à :
server {
# Catégories principales : /chaussures-homme.html → /collections/chaussures-homme
rewrite ^/([a-z-]+)\.html$ /collections/$1 permanent;
# Fiches produit : /chaussures-homme/nike-air-max-90.html → /collections/chaussures-homme/nike-air-max-90
rewrite ^/([a-z-]+)/([a-z0-9-]+)\.html$ /collections/$1/$2 permanent;
# Pages de pagination : /chaussures-homme.html?p=3 → /collections/chaussures-homme?page=3
if ($arg_p) {
rewrite ^/([a-z-]+)\.html$ /collections/$1?page=$arg_p permanent;
}
# Anciennes pages de marques (supprimées) → catégorie parente
rewrite ^/marques/([a-z-]+)/?$ /collections permanent;
# Catch-all pour les URLs non mappées → 410 Gone (pas 404)
# Uniquement pour les anciennes URLs confirmées comme supprimées
location ~* ^/(ancienne-promo|outlet-2024|flash-sale)/ {
return 410;
}
}
Quelques points critiques ici :
Utilisez permanent (301) pour les changements de structure définitifs. La distinction entre 301 et 302 est fondamentale : une 302 sur une migration permanente signale à Google que l'ancienne URL reste la référence. Le transfert de signaux SEO est retardé, parfois indéfiniment.
Le catch-all en 410 plutôt qu'en 404. Pour les URLs que vous supprimez intentionnellement (promotions expirées, pages saisonnières), le code 410 Gone indique explicitement à Google que la page n'existe plus et ne reviendra pas. Google désindexe les 410 plus rapidement que les 404 (documentation Google sur les codes HTTP).
Ne redirigez pas massivement vers la homepage. C'est tentant pour les URLs orphelines, mais Google traite les redirections massives vers la homepage comme des soft 404. Si 2 000 anciennes URLs pointent toutes vers /, vous ne transférez aucun signal de lien.
Le piège des paramètres d'URL
Les URLs avec paramètres (?color=red&size=42) sont le trou noir des migrations. Votre ancien site en génère potentiellement des milliers via les filtres à facettes, le tri, la pagination. Trois stratégies selon le cas :
- Paramètres indexés (vérifié dans GSC > rapport "Pages") : mapper individuellement ou par pattern vers l'URL équivalente sur le nouveau site.
- Paramètres non indexés mais avec backlinks : rediriger vers la page de destination la plus proche (la catégorie sans filtre, par exemple).
- Paramètres purement techniques (session ID, tracking) : ignorer. Ils ne sont pas indexés, pas liés. Ils retourneront naturellement en 404 et sortiront de l'index.
Si vos canonicals étaient correctement implémentés sur l'ancien site, les URLs à paramètres indexées devraient être limitées. Si ce n'est pas le cas, vous risquez de découvrir de l'index bloat — et la migration est l'occasion de nettoyer.
Tests pré-déploiement : valider avant le go-live
Déployer des redirections sans les tester, c'est comme pusher en production sans CI. Pourtant, la majorité des migrations ne prévoient aucune phase de validation systématique des redirections.
Tester chaque règle avec curl
Avant le go-live, votre fichier de mapping doit être vérifié URL par URL. Un script bash qui vérifie le code de statut et la destination de chaque redirection :
#!/bin/bash
# redirect_checker.sh
# Input : CSV avec colonnes old_url,expected_new_url
# Exécution sur l'environnement de staging
STAGING_HOST="https://staging.monsite.fr"
ERRORS=0
TOTAL=0
while IFS=',' read -r old_url expected_url; do
TOTAL=$((TOTAL + 1))
# Remplacer le domaine de production par le staging
staging_url="${old_url/https:\/\/www.monsite.fr/$STAGING_HOST}"
# Suivre la redirection et capturer le code + la destination
response=$(curl -s -o /dev/null -w "%{http_code} %{redirect_url}" -L --max-redirs 1 "$staging_url")
http_code=$(echo "$response" | awk '{print $1}')
redirect_target=$(echo "$response" | awk '{print $2}')
# Normaliser pour la comparaison
expected_normalized="${expected_url/https:\/\/www.monsite.fr/$STAGING_HOST}"
if [[ "$http_code" != "301" ]] && [[ "$http_code" != "200" ]]; then
echo "ERREUR [$http_code] $old_url → attendu: $expected_url"
ERRORS=$((ERRORS + 1))
elif [[ -n "$redirect_target" ]] && [[ "$redirect_target" != "$expected_normalized"* ]]; then
echo "MAUVAISE DEST $old_url → obtenu: $redirect_target | attendu: $expected_url"
ERRORS=$((ERRORS + 1))
fi
done < mapping.csv
echo "--- Résultat : $ERRORS erreurs sur $TOTAL URLs testées ---"
exit $ERRORS
Exécutez ce script sur votre environnement de staging. Il doit passer à zéro erreur avant tout déploiement. Intégrez-le dans votre pipeline CI/CD si votre workflow le permet.
Vérifier l'absence de chaînes de redirections
Un problème fréquent post-migration : des chaînes de redirections apparaissent parce que les anciennes redirections (mises en place lors de refontes précédentes) n'ont pas été mises à jour. Si /ancien-produit redirigeait déjà vers /produit-v2, et que la migration envoie /produit-v2 vers /collections/produit, vous obtenez une chaîne A → B → C.
Dans Screaming Frog, lancez un crawl en mode "List" sur vos anciennes URLs. Filtrez les résultats sur "Redirect Chains" > 1 hop. Chaque chaîne identifiée doit être aplatie : la redirection de /ancien-produit doit pointer directement vers /collections/produit.
Contrôler les meta tags sur les pages de destination
Une redirection correcte vers une page dont les meta tags sont cassés ne vaut rien. Vérifiez que chaque page de destination sur le nouveau site a :
- Un title tag unique et pertinent
- Une meta description renseignée
- Pas de meta robots noindex accidentel (erreur classique quand l'environnement de staging passe en production avec les directives de blocage encore en place)
- Un canonical self-referencing pointant vers la nouvelle URL (pas l'ancienne)
- Des balises hreflang cohérentes si le site est multilingue
Le jour J : séquence de déploiement
L'ordre des opérations le jour de la migration compte. Voici la séquence qui minimise la fenêtre de vulnérabilité.
Étape 1 : Activer les redirections AVANT de couper l'ancien site
Si votre migration implique un changement de domaine ou de sous-domaine, les règles de redirection doivent être actives sur l'ancien serveur avant que le DNS ne propage. Concrètement :
- Déployez les règles de redirection sur l'ancien serveur/reverse proxy.
- Testez manuellement 20-30 URLs critiques avec
curl -I. - Seulement ensuite, basculez le DNS ou le reverse proxy vers la nouvelle stack.
Si vous coupez l'ancien serveur avant que les redirections soient en place, vous avez une fenêtre où Googlebot rencontre des 5xx ou des timeout. Chaque erreur est comptabilisée dans le rapport "Exploration" de Search Console et peut déclencher une réduction temporaire du taux de crawl.
Étape 2 : Mettre à jour le sitemap XML
Soumettez immédiatement un nouveau sitemap XML dans Search Console avec uniquement les nouvelles URLs. Ne conservez pas les anciennes URLs dans le sitemap — elles renverraient Googlebot vers des redirections, ce qui gaspille du crawl budget.
Si vous changez de domaine, ajoutez et vérifiez le nouveau domaine dans Search Console, puis utilisez l'outil "Changement d'adresse" (Settings > Change of address). Cet outil signale explicitement à Google que la migration est intentionnelle.
Étape 3 : Forcer le re-crawl des pages prioritaires
Pour les 100 à 200 pages les plus stratégiques, utilisez l'API d'inspection d'URL de Search Console pour demander une indexation immédiate. La limite est d'environ 200 requêtes par jour et par propriété — concentrez-vous sur les pages à fort trafic et à fort potentiel de backlinks.
Étape 4 : Monitorer les erreurs de crawl en temps réel
Les premières 48 à 72 heures après le go-live sont critiques. Le rapport "Exploration" de Search Console a un délai de 2-3 jours. Pour un feedback immédiat, analysez vos logs serveur :
# Extraire les 404 rencontrées par Googlebot dans les premières 24h
grep "Googlebot" /var/log/nginx/access.log \
| awk '$9 == 404 {print $7}' \
| sort | uniq -c | sort -rn \
| head -50 > googlebot_404_post_migration.txt
Chaque 404 dans ce fichier est une URL que Google essaie d'atteindre et qui n'a pas de redirection. Traitez les en priorité par volume de hits : si Googlebot demande /old-promo-page 15 fois en 24h, c'est qu'il a des signaux forts (backlinks, présence dans l'index) pour cette URL.
Un outil de monitoring SEO comme Seogard détecte ce type de régression automatiquement — les 404 apparues post-migration, les meta noindex accidentels, les canonicals cassés — sans attendre que Search Console remonte les données avec 3 jours de retard.
Monitoring post-migration : les 90 jours critiques
Le mythe du "la migration est terminée quand les redirections sont en place" est exactement ça : un mythe. Le vrai travail de validation s'étend sur 8 à 12 semaines.
Semaine 1 : stabilisation
- Vérifiez quotidiennement les logs serveur pour les 404 Googlebot.
- Dans Search Console, surveillez le rapport "Pages" pour détecter une hausse soudaine de "Pages non indexées" avec la raison "Introuvable (404)".
- Contrôlez que le taux de crawl ne s'effondre pas (rapport "Statistiques d'exploration").
Semaines 2-4 : consolidation de l'index
- Comparez le nombre de pages indexées avant/après. Une baisse de 10-15% dans les deux premières semaines est normale — les anciennes URLs sortent de l'index avant que les nouvelles ne soient toutes intégrées. Au-delà de 20%, investiguez.
- Vérifiez les positions des 50 requêtes principales dans Search Console > Performances. Une migration réussie montre une récupération progressive dès la semaine 2-3.
- Surveillez vos Core Web Vitals — une migration est souvent accompagnée d'un changement de stack technique, et les régressions de performance (LCP, CLS, INP) sont fréquentes.
Semaines 4-12 : validation long terme
- Le trafic organique doit retrouver son niveau pré-migration (±10%) dans les 4 à 8 semaines pour une migration bien exécutée.
- Si ce n'est pas le cas après 8 semaines, les causes les plus fréquentes sont : des redirections manquantes sur des URLs à backlinks, des problèmes de canonical qui créent de la cannibalisation, ou des pages critiques bloquées involontairement par le robots.txt.
Le scénario concret : retour sur l'e-commerce Magento → Shopify
Reprenons notre e-commerce de 18 000 pages. Après le diagnostic initial (47% de perte), voici ce qui a été corrigé :
- 3 200 URLs sans redirection : identifiées par croisement logs Googlebot + export Ahrefs. Mapping ajouté en lot via l'app de redirections Shopify + un worker Cloudflare pour les patterns complexes que Shopify ne supporte pas nativement.
- 450 chaînes de redirections : héritées de la migration précédente (Magento 1 vers Magento 2, 3 ans plus tôt). Aplaties en redirections directes.
- 12 pages catégories avec meta robots noindex : le thème Shopify avait un tag
noindexconditionnel sur les collections sans produits. Trois catégories étaient temporairement vides pendant la réimportation du catalogue. - Sitemap contenant encore les anciennes URLs : le sitemap auto-généré par Shopify était correct, mais un sitemap statique hérité de Magento avait été uploadé manuellement dans
/sitemap-legacy.xmlet était encore référencé dans le robots.txt.
Résultat après correction : récupération à 92% du trafic organique en 6 semaines, puis dépassement du niveau pré-migration à la semaine 10 grâce au nettoyage des pages en doublon et des chaînes de redirections.
Les edge cases que personne ne mentionne
Redirections et JavaScript-rendered content
Si votre ancien site servait du contenu en client-side rendering (React SPA, Angular), certaines URLs n'ont peut-être jamais été correctement indexées. Avant de les mapper, vérifiez dans Search Console (Inspection d'URL > "Voir la page explorée") si Google avait réellement rendu et indexé le contenu. Rediriger une URL que Google n'a jamais indexée est inutile — vous pouvez la laisser retourner 404 ou 410 sans impact.
Redirections HTTPS/HTTP et www/non-www
Une migration est souvent l'occasion de consolider les variantes de protocole et de sous-domaine. Assurez-vous que les quatre combinaisons redirigent vers la forme canonique :
http://monsite.fr/page→https://www.monsite.fr/pagehttp://www.monsite.fr/page→https://www.monsite.fr/pagehttps://monsite.fr/page→https://www.monsite.fr/page
Si vous changez de domaine en même temps, ces redirections doivent pointer directement vers la nouvelle URL finale sur le nouveau domaine. Pas de chaîne http://ancien.fr → https://ancien.fr → https://nouveau.fr.
Images et ressources statiques
Les URLs d'images apparaissent dans Google Images et génèrent du trafic. Si votre CDN ou votre structure de dossiers statiques change, ces URLs doivent aussi être redirigées. C'est un point aveugle fréquent : l'équipe SEO mappe les pages, l'équipe dev change le CDN, et 5 000 URLs d'images optimisées renvoient en 404 dans Google Images.
Durée de vie des redirections
Google recommande de maintenir les redirections 301 pendant au moins un an après la migration (source : Google Search Central). En pratique, pour les URLs avec des backlinks, maintenez-les indéfiniment. Le coût serveur d'une règle de redirection est négligeable comparé à la perte d'un backlink de qualité.
Pages indexées malgré un noindex pré-migration
Certaines pages que vous aviez marquées noindex étaient peut-être quand même dans l'index de Google (ça arrive si le noindex a été ajouté récemment ou si Googlebot ne l'a pas encore recrawlée). Si ces pages avaient des backlinks, elles méritent une redirection même si elles n'étaient "pas censées" être indexées.
Checklist récapitulative par phase
Pré-migration (J-30 à J-7) :
- Crawl complet Screaming Frog avec config exhaustive
- Export GSC (pages indexées + pages les plus liées)
- Export backlinks (Ahrefs / Majestic)
- Export analytics (landing pages organiques 12 mois)
- Fusion et déduplication → fichier maître
- Construction du mapping (règles par pattern + mapping individuel top pages)
- Implémentation des règles sur l'environnement de staging
- Tests automatisés curl sur 100% du mapping
- Vérification des chaînes de redirections
- Audit meta tags des pages de destination
Jour J :
- Activation des redirections sur l'ancien serveur
- Test manuel des 30 URLs critiques
- Bascule DNS / reverse proxy
- Soumission du nouveau sitemap dans GSC
- Suppression de l'ancien sitemap
- Demande d'indexation via l'API pour le top 200 pages
- Monitoring logs serveur en temps réel
Post-migration (J+1 à J+90) :
- Analyse quotidienne des 404 Googlebot (semaine 1)
- Suivi du nombre de pages indexées (hebdomadaire)
- Suivi des positions top 50 requêtes (hebdomadaire)
- Audit Core Web Vitals sur la nouvelle stack
- Bilan à J+30, J+60, J+90
Chaque item manqué dans cette checklist est un vecteur de perte de trafic. La différence entre une migration qui récupère en 3 semaines et une qui met 5 mois tient rarement à un problème technique unique — c'est l'accumulation de petits oublis qui s'additionne.
Un plan de redirection exhaustif, testé automatiquement avant le go-live et monitoré en continu après, transforme une migration à risque en transition maîtrisée. Des outils comme Seogard permettent de détecter les régressions — 404 apparues, canonicals incohérents, meta disparues — dans les heures qui suivent le déploiement, là où Search Console met plusieurs jours à remonter les signaux.