[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f7RcY-eZ0WiZWcUCFst5e0HjuwdONSmOXm_VipiPkl0s":3,"$fXRxLbm3BXPYDzuEWQFzirLGs97rdrktdQQjFFi2TKiE":24},{"_id":4,"slug":5,"__v":6,"author":7,"body":8,"canonical":9,"category":10,"createdAt":11,"date":12,"description":13,"htmlContent":14,"image":15,"imageAlt":15,"readingTime":16,"tags":17,"title":22,"updatedAt":23},"69d7e9c3aa6b273b0c95cc57","migration-http-vers-https-checklist-seo-complete",0,"Equipe Seogard","En 2024, un e-commerce mode de 12 000 pages a perdu 34 % de son trafic organique pendant 11 semaines après une migration HTTPS mal exécutée. Pas à cause du certificat — à cause de redirections en chaîne, de canonical HTTP résiduels dans le `\u003Chead>`, et d'un sitemap qui pointait encore vers les anciennes URLs. Tout était techniquement \"en HTTPS\", mais Google continuait d'indexer les versions HTTP.\n\nLa migration HTTP vers HTTPS est considérée comme triviale par beaucoup de développeurs. Installer un certificat Let's Encrypt, activer une règle de redirect, terminé. En réalité, c'est une migration d'URLs à part entière — chaque URL HTTP est une ancienne URL qui doit être correctement redirigée, désindexée, et remplacée dans tous les signaux que Google utilise pour évaluer votre site.\n\n## Pré-requis : auditer l'état HTTP avant de toucher quoi que ce soit\n\nAvant d'activer la moindre redirection, vous avez besoin d'un snapshot complet de votre site en HTTP. Sans cette baseline, vous n'aurez aucun moyen de mesurer l'impact de la migration ni de diagnostiquer les problèmes post-migration.\n\n### Crawl complet du site HTTP\n\nLancez un crawl exhaustif avec Screaming Frog (ou Sitebulb) en configurant le crawler sur le protocole `http://`. Exportez :\n\n- La liste complète des URLs crawlées (HTML, images, CSS, JS)\n- Les canonical déclarés sur chaque page\n- Les hreflang (si site multilingue — voir [architecture technique multilingue](/blog/seo-multilingue-architecture-technique-optimale))\n- Les liens internes et leur protocole\n- Les réponses HTTP (200, 301, 404, etc.)\n\nCe crawl est votre référence. Vous le comparerez au crawl post-migration pour identifier chaque divergence.\n\n### Snapshot des positions et du trafic\n\nDans Google Search Console, exportez les données de performance (clics, impressions, CTR, position moyenne) par page sur les 3 derniers mois. Faites la même chose dans votre outil analytics. Ces données serviront de baseline pour mesurer l'impact.\n\nSi vous suivez des [KPIs SEO techniques](/blog/mesurer-l-impact-seo-technique-quels-kpis-suivre) avec des dashboards automatisés, prenez un snapshot daté le jour J-1 de la migration.\n\n### Inventaire des signaux externes\n\nVos backlinks pointent vers des URLs HTTP. Votre sitemap est en HTTP. Vos profils Google Business, vos réseaux sociaux, vos annuaires — tout référence le protocole HTTP. Listez ces sources. Vous ne pourrez pas toutes les mettre à jour immédiatement, mais vous devez savoir d'où viennent les signaux pour prioriser.\n\nUtilisez Ahrefs ou Majestic pour exporter la liste des backlinks avec le protocole exact (http vs https). Triez par Domain Rating : les backlinks les plus puissants méritent une demande de mise à jour auprès des webmasters.\n\n## Certificat SSL/TLS : choix et installation\n\n### Quel type de certificat\n\nPour la majorité des sites, un certificat DV (Domain Validation) via Let's Encrypt suffit. Google ne fait aucune distinction SEO entre un certificat DV gratuit et un certificat EV à 500 €/an — c'est confirmé dans la [documentation Google sur HTTPS](https://developers.google.com/search/docs/crawling-indexing/https).\n\nSi vous gérez un site avec des sous-domaines multiples (shop.example.fr, blog.example.fr, app.example.fr), optez pour un certificat wildcard (`*.example.fr`) pour simplifier la gestion.\n\n### Installation et vérification\n\nSur un serveur Ubuntu avec Nginx et Certbot :\n\n```bash\n# Installation de Certbot pour Nginx\nsudo apt update && sudo apt install certbot python3-certbot-nginx -y\n\n# Génération du certificat (wildcard avec DNS challenge)\nsudo certbot certonly --manual --preferred-challenges=dns \\\n  -d example.fr -d *.example.fr\n\n# Vérification de la date d'expiration\nsudo openssl x509 -in /etc/letsencrypt/live/example.fr/fullchain.pem -noout -dates\n\n# Test de la configuration SSL\nopenssl s_client -connect example.fr:443 -servername example.fr\n```\n\nVérifiez que la chaîne de certificats est complète (certificat du serveur + intermédiaire). Une chaîne incomplète provoque des erreurs sur certains clients et peut empêcher Googlebot d'accéder au site. Testez avec [SSL Labs Server Test](https://www.ssllabs.com/ssltest/) — visez un grade A minimum.\n\n### Configuration TLS dans Nginx\n\nLa configuration TLS impacte à la fois la sécurité et la performance (et donc le crawl). Voici une configuration Nginx production-ready :\n\n```nginx\nserver {\n    listen 443 ssl http2;\n    server_name example.fr www.example.fr;\n\n    ssl_certificate /etc/letsencrypt/live/example.fr/fullchain.pem;\n    ssl_certificate_key /etc/letsencrypt/live/example.fr/privkey.pem;\n\n    # Protocoles et ciphers modernes\n    ssl_protocols TLSv1.2 TLSv1.3;\n    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;\n    ssl_prefer_server_ciphers off;\n\n    # OCSP Stapling (réduit la latence du handshake TLS)\n    ssl_stapling on;\n    ssl_stapling_verify on;\n    resolver 1.1.1.1 8.8.8.8 valid=300s;\n\n    # Session caching\n    ssl_session_cache shared:SSL:10m;\n    ssl_session_timeout 1d;\n    ssl_session_tickets off;\n\n    # HSTS (à activer APRÈS validation complète — voir section dédiée)\n    # add_header Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\" always;\n\n    root /var/www/example.fr;\n    index index.html;\n}\n```\n\nPoint critique : ne commentez pas le HSTS par défaut. Activez-le uniquement après avoir validé que tout fonctionne en HTTPS. Un HSTS mal configuré avec `includeSubDomains` sur un sous-domaine qui n'a pas de certificat rend ce sous-domaine totalement inaccessible.\n\n## Redirections : le cœur de la migration\n\nC'est ici que 80 % des migrations échouent. La redirection HTTP → HTTPS est une migration d'URL. Chaque URL HTTP doit retourner une 301 vers son équivalent HTTPS exact — même path, mêmes query parameters.\n\n### Règle de redirection globale\n\nDans Nginx, la redirection doit être gérée dans un bloc `server` dédié au port 80 :\n\n```nginx\nserver {\n    listen 80;\n    server_name example.fr www.example.fr;\n\n    # Redirection 301 globale HTTP → HTTPS\n    # $request_uri préserve le path ET les query strings\n    return 301 https://$host$request_uri;\n}\n```\n\nSur Apache, dans le `.htaccess` ou la configuration du VirtualHost :\n\n```apache\n\u003CVirtualHost *:80>\n    ServerName example.fr\n    ServerAlias www.example.fr\n\n    RewriteEngine On\n    RewriteCond %{HTTPS} off\n    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\n\u003C/VirtualHost>\n```\n\n### Les erreurs classiques qui détruisent le trafic\n\n**Chaînes de redirections.** Le scénario le plus fréquent : `http://example.fr` → `https://example.fr` → `https://www.example.fr`. Deux redirections en chaîne. Googlebot les suit, mais chaque hop dilue le PageRank transmis et ralentit le crawl. Si vous gérez aussi la migration www vers non-www (ou l'inverse), faites une seule redirection directe :\n\n```nginx\n# MAUVAIS : chaîne de redirections\nserver {\n    listen 80;\n    server_name example.fr;\n    return 301 https://example.fr$request_uri;\n    # Puis un autre bloc redirige https://example.fr → https://www.example.fr\n}\n\n# BON : redirection directe vers la destination finale\nserver {\n    listen 80;\n    server_name example.fr www.example.fr;\n    return 301 https://www.example.fr$request_uri;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name example.fr;\n    return 301 https://www.example.fr$request_uri;\n}\n```\n\n**Redirections en 302 au lieu de 301.** Certains frameworks (Express.js, Django) redirigent en 302 par défaut. Une 302 indique à Google que la redirection est temporaire — il peut continuer d'indexer l'URL HTTP. Vérifiez explicitement le code de statut dans vos headers.\n\n**Query strings perdues.** Si votre e-commerce utilise des paramètres de filtrage (`/chaussures?couleur=rouge&taille=42`), vérifiez que la redirection les préserve. Avec `$request_uri` dans Nginx, c'est le cas. Avec certaines configurations CDN (Cloudflare Page Rules mal configurées), les query strings peuvent être strippées.\n\n### Vérification post-redirection\n\nTestez un échantillon d'URLs avec curl pour valider le comportement exact :\n\n```bash\n# Vérifier le code de redirection et la destination\ncurl -I http://www.example.fr/categorie/chaussures-homme?tri=prix-asc\n\n# Résultat attendu :\n# HTTP/1.1 301 Moved Permanently\n# Location: https://www.example.fr/categorie/chaussures-homme?tri=prix-asc\n\n# Vérifier qu'il n'y a pas de chaîne\ncurl -ILs http://example.fr/categorie/chaussures-homme 2>&1 | grep -E \"HTTP/|Location:\"\n\n# Résultat attendu : un seul 301, puis un 200 sur la destination HTTPS finale\n```\n\nAvec Screaming Frog, recrawlez le site en mode `http://` et vérifiez que toutes les URLs retournent un 301 vers leur équivalent HTTPS exact. Exportez les redirections en chaîne (Redirect Chains report) et corrigez chaque cas.\n\n## Mixed content : le piège silencieux\n\nVotre page se charge en HTTPS, mais elle inclut une image en `http://`, un script en `http://`, ou une feuille CSS en `http://`. C'est du mixed content. Les navigateurs modernes bloquent le mixed content actif (scripts, iframes) et affichent des avertissements pour le mixed content passif (images). Google ne considère pas une page comme \"sécurisée\" si elle contient du mixed content actif.\n\n### Identifier le mixed content\n\nDans Chrome DevTools (onglet Console ou Security), les erreurs de mixed content apparaissent clairement. Mais pour un site de 12 000 pages, vous ne pouvez pas vérifier manuellement chaque page.\n\nScreaming Frog permet de détecter le mixed content : crawlez le site en HTTPS, puis filtrez les ressources externes chargées en HTTP (Images > Protocol = HTTP, Scripts > Protocol = HTTP, etc.).\n\nPour une approche plus systématique, utilisez un [header CSP en mode report-only](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only) :\n\n```nginx\n# Dans votre configuration Nginx HTTPS\nadd_header Content-Security-Policy-Report-Only\n    \"default-src https: 'unsafe-inline' 'unsafe-eval'; report-uri /csp-report-endpoint\"\n    always;\n```\n\nPuis implémentez un endpoint qui collecte les violations :\n\n```javascript\n// Express.js — endpoint de collecte des rapports CSP\nconst express = require('express');\nconst app = express();\n\napp.use('/csp-report-endpoint', express.json({ type: 'application/csp-report' }));\n\napp.post('/csp-report-endpoint', (req, res) => {\n  const report = req.body['csp-report'];\n  if (report && report['blocked-uri'] && report['blocked-uri'].startsWith('http:')) {\n    console.log(JSON.stringify({\n      page: report['document-uri'],\n      blockedResource: report['blocked-uri'],\n      directive: report['violated-directive'],\n      timestamp: new Date().toISOString()\n    }));\n  }\n  res.sendStatus(204);\n});\n\napp.listen(3000);\n```\n\nLaissez tourner 48 heures en production. Vous obtiendrez la liste exhaustive de toutes les ressources HTTP chargées sur vos pages HTTPS, classées par page.\n\n### Corriger le mixed content\n\nLes sources principales de mixed content :\n\n- **Images hardcodées en base de données** : les URLs d'images insérées dans le contenu éditorial via un CMS. Requête SQL pour corriger en masse :\n\n```sql\n-- WordPress : mise à jour des URLs dans le contenu des articles\nUPDATE wp_posts\nSET post_content = REPLACE(post_content, 'http://cdn.example.fr', 'https://cdn.example.fr')\nWHERE post_content LIKE '%http://cdn.example.fr%';\n\n-- Idem pour les métadonnées (images à la une, etc.)\nUPDATE wp_postmeta\nSET meta_value = REPLACE(meta_value, 'http://cdn.example.fr', 'https://cdn.example.fr')\nWHERE meta_value LIKE '%http://cdn.example.fr%';\n```\n\n- **Scripts et stylesheets tiers** : Google Fonts, bibliothèques jQuery hébergées en HTTP, pixels de tracking anciens. Mettez à jour les références ou passez en protocol-relative (`//fonts.googleapis.com/...`) — bien que l'utilisation explicite de `https://` soit préférable.\n\n- **Ressources injectées par JavaScript** : certains widgets (chat, analytics, pubs) génèrent dynamiquement des URLs HTTP. Vérifiez les scripts tiers et mettez à jour les versions.\n\nSi vous utilisez un CDN comme Cloudflare, activez \"Automatic HTTPS Rewrites\" pour corriger à la volée le mixed content passif. C'est un filet de sécurité, pas une solution pérenne — corrigez les sources.\n\n## Signaux de référencement : tout mettre à jour\n\nLa redirection seule ne suffit pas. Google utilise de multiples signaux pour déterminer l'URL canonique d'une page. Si ces signaux se contredisent (la redirection dit HTTPS, mais le canonical dit HTTP), Google hésite et peut conserver l'ancienne URL dans l'index pendant des semaines.\n\n### Canonical tags\n\nChaque page doit déclarer un canonical en HTTPS :\n\n```html\n\u003C!-- AVANT migration -->\n\u003Clink rel=\"canonical\" href=\"http://www.example.fr/categorie/chaussures-homme\" />\n\n\u003C!-- APRÈS migration -->\n\u003Clink rel=\"canonical\" href=\"https://www.example.fr/categorie/chaussures-homme\" />\n```\n\nC'est le signal le plus oublié. Dans un CMS headless, le canonical est souvent généré dynamiquement côté application. Vérifiez le code source de génération, pas seulement le rendu d'une page.\n\nSi votre site utilise un [headless CMS](/blog/headless-cms-et-seo-avantages-et-risques-techniques), le canonical est typiquement construit à partir d'une variable d'environnement (`SITE_URL` ou équivalent). Changez cette variable de `http://` en `https://` et redeployez. Puis validez le rendu côté serveur.\n\n### Sitemap XML\n\nGénérez un nouveau sitemap avec toutes les URLs en HTTPS. Soumettez-le dans Google Search Console. Si votre ancien sitemap est référencé dans le `robots.txt`, mettez à jour cette référence :\n\n```\n# robots.txt — APRÈS migration\nUser-agent: *\nAllow: /\n\nSitemap: https://www.example.fr/sitemap.xml\n```\n\nNe supprimez pas l'ancien sitemap HTTP immédiatement. Pendant la phase de transition (4-8 semaines), avoir les deux sitemaps permet à Google de mieux comprendre la correspondance entre anciennes et nouvelles URLs.\n\n### Hreflang (sites multilingues)\n\nSi vous avez des annotations hreflang, chaque URL référencée doit passer en HTTPS — y compris les URLs vers les versions linguistiques alternatives hébergées sur d'autres domaines ou sous-domaines. Un hreflang qui pointe vers `http://` alors que la page redirige en HTTPS crée une incohérence qui peut déstabiliser l'indexation multilingue.\n\n### Liens internes\n\nMême si les redirections 301 fonctionnent, vos liens internes doivent pointer directement vers les URLs HTTPS. Chaque lien interne en HTTP force une redirection, ce qui :\n- Ajoute 50-200 ms de latence par requête\n- Consomme inutilement du [crawl budget](/blog/mega-menus-et-seo-attention-au-crawl-budget)\n- Transmet un signal ambigu à Google sur le protocole canonique\n\nFaites un search-and-replace dans votre base de données, vos templates, et vos fichiers de configuration. Puis recrawlez pour vérifier qu'aucun lien interne ne pointe encore vers HTTP.\n\n### Open Graph et données structurées\n\nLes balises `og:url`, `og:image`, et les URLs dans le JSON-LD (schema.org) doivent toutes passer en HTTPS. C'est souvent oublié parce que ces balises n'impactent pas directement le ranking — mais elles impactent l'affichage dans les SERP (rich snippets) et le partage social.\n\n## Google Search Console : propriétés et validation\n\nGoogle Search Console traite `http://` et `https://` comme deux propriétés distinctes. C'est un point que beaucoup de SEO sous-estiment.\n\n### Créer la propriété HTTPS\n\nSi vous utilisez une propriété de type \"Domaine\" (vérifiée par DNS), elle couvre automatiquement HTTP et HTTPS. Vous n'avez rien à faire.\n\nSi vous utilisez une propriété de type \"Préfixe d'URL\" (la majorité des cas historiques), vous devez créer une nouvelle propriété `https://www.example.fr` et la vérifier. Ne supprimez pas l'ancienne propriété `http://` — conservez-la pour surveiller la décroissance des impressions HTTP et détecter d'éventuels problèmes.\n\nSoumettez le nouveau sitemap HTTPS dans la nouvelle propriété. Consultez les [rapports Search Console que vous ignorez peut-être](/blog/google-search-console-les-rapports-que-vous-ignorez) pour identifier les signaux de migration réussie.\n\n### Surveiller l'indexation post-migration\n\nDans la nouvelle propriété HTTPS, surveillez :\n\n- **Couverture de l'index** : les pages HTTPS doivent apparaître comme \"Valides\" progressivement. Les pages HTTP doivent passer en \"Exclues — Page avec redirection\".\n- **Sitemaps** : vérifiez que le nouveau sitemap est traité et que les URLs sont \"Découvertes\".\n- **Performances** : comparez les clics/impressions entre les propriétés HTTP et HTTPS sur une fenêtre glissante de 4 semaines.\n\nLa transition complète de l'index prend typiquement 2 à 8 semaines pour un site de 10 000-15 000 pages. Les sites avec un crawl fréquent (médias, e-commerce avec stock en temps réel) migrent plus vite parce que Googlebot passe plus souvent.\n\nPour automatiser cette surveillance, l'[API Search Console](/blog/search-console-api-automatiser-le-reporting-seo) permet d'extraire les données de couverture et de performance par propriété, et de déclencher des alertes si les métriques HTTPS ne progressent pas comme attendu.\n\n## HSTS : verrouiller la migration\n\nLe header HTTP Strict-Transport-Security (HSTS) indique aux navigateurs de ne jamais charger votre site en HTTP, même si l'utilisateur tape `http://` dans la barre d'adresse. C'est la dernière étape de la migration — et elle est irréversible si vous activez le preload.\n\n### Déploiement progressif du HSTS\n\nActivez HSTS par paliers pour limiter les risques :\n\n**Semaine 1-2 : max-age court, sans includeSubDomains**\n```nginx\nadd_header Strict-Transport-Security \"max-age=300\" always;\n```\n5 minutes. Si quelque chose casse, le navigateur oubliera la directive rapidement.\n\n**Semaine 3-4 : augmenter le max-age**\n```nginx\nadd_header Strict-Transport-Security \"max-age=86400\" always;\n```\n24 heures. Surveillez les erreurs.\n\n**Semaine 5+ : max-age long avec includeSubDomains**\n```nginx\nadd_header Strict-Transport-Security \"max-age=63072000; includeSubDomains\" always;\n```\n2 ans. C'est la valeur recommandée pour la soumission à la [HSTS preload list](https://hstspreload.org/).\n\n**Attention critique** : `includeSubDomains` signifie que TOUS vos sous-domaines (staging.example.fr, api.example.fr, legacy-app.example.fr) doivent être accessibles en HTTPS avec un certificat valide. Si un sous-domaine interne utilise encore HTTP, il deviendra inaccessible pour tous les navigateurs qui ont reçu le header HSTS. Auditez vos sous-domaines avant d'activer cette directive.\n\n### HSTS Preload\n\nLe preload inscrit votre domaine dans une liste intégrée aux navigateurs (Chrome, Firefox, Safari, Edge). Même la première visite sera forcée en HTTPS, avant même que le navigateur reçoive le header HSTS. C'est le niveau maximum de protection.\n\nSoumettez votre domaine sur [hstspreload.org](https://hstspreload.org/) uniquement quand vous êtes absolument certain que le HTTPS fonctionne partout. Le retrait de la preload list prend plusieurs mois.\n\n## Scénario réel : migration d'un e-commerce de 15 000 pages\n\nUn e-commerce spécialisé en équipement outdoor. 15 200 pages indexées (fiches produits, catégories, pages CMS, blog). Stack : Nginx, PHP-FPM, WordPress + WooCommerce. CDN Cloudflare. 42 000 visites organiques/mois.\n\n### Chronologie\n\n**J-14** : crawl complet HTTP avec Screaming Frog. Export de 15 200 URLs en 200, 847 canonical tags, 0 hreflang (site monolingue). Identification de 312 liens internes hardcodés en `http://` dans les descriptions produit (injectées via l'éditeur WYSIWYG).\n\n**J-7** : installation du certificat Let's Encrypt wildcard. Test SSL Labs : grade A. Mise à jour de `WP_HOME` et `WP_SITEURL` en `https://`. Exécution des requêtes SQL pour corriger les URLs dans `wp_posts` et `wp_postmeta`. Mise à jour du CDN Cloudflare : Full (Strict) SSL mode + Automatic HTTPS Rewrites activé.\n\n**J-1** : header CSP report-only déployé pendant 24h. Détection de 23 ressources mixtes (images de fournisseurs référencées en HTTP dans des fiches produit importées par flux). Correction manuelle.\n\n**J0** : activation de la redirection 301 HTTP → HTTPS dans Nginx. Déploiement du nouveau `robots.txt` et `sitemap.xml` en HTTPS. Création de la propriété HTTPS dans Search Console. Soumission du sitemap. HSTS activé avec `max-age=300`.\n\n**J+1** : crawl de vérification complet en HTTPS. 15 200 pages en 200. 0 mixed content détecté. 0 chaîne de redirection. Tous les canonical en HTTPS. Liens internes : 99,7 % en HTTPS (8 liens résiduels dans des widgets de sidebar, corrigés dans la journée).\n\n**J+3** : Search Console affiche 4 200 pages HTTPS indexées. Les impressions HTTP commencent à baisser.\n\n**J+14** : 12 800 pages HTTPS indexées. Trafic organique : -8 % vs baseline (fluctuation normale pendant la transition).\n\n**J+21** : HSTS passé à `max-age=86400`.\n\n**J+30** : 15 100 pages HTTPS indexées (99,3 %). Trafic organique revenu au niveau baseline (-1 %, dans la marge d'erreur).\n\n**J+45** : HSTS passé à `max-age=63072000; includeSubDomains`. Trafic organique : +3 % vs baseline (corrélation probable avec une légère amélioration du ranking — HTTPS est un signal de classement confirmé par Google, même si son poids est modeste).\n\n**J+60** : soumission au HSTS preload. Propriété HTTP Search Console conservée en lecture seule pour archivage.\n\n### Leçons de ce cas\n\nLe creux de -8 % à J+14 est normal et documenté. Google doit recrawler et réindexer chaque page dans sa nouvelle version HTTPS. Pendant cette période, certaines pages sont encore indexées en HTTP, d'autres en HTTPS, et les signaux sont fragmentés. La durée du creux dépend directement de la fréquence de crawl de votre site.\n\nLa correction des 312 liens internes hardcodés en base de données a été le point le plus chronophage (3 heures de vérification et de requêtes SQL). Sur un site avec un contenu éditorial plus riche (média, blog avec des milliers d'articles), cette étape peut prendre une journée complète.\n\n## Monitoring post-migration et détection de régression\n\nLa migration ne s'arrête pas à J+30. Des régressions peuvent survenir des mois plus tard :\n\n- Un développeur ajoute une nouvelle page avec un canonical en HTTP parce que la variable d'environnement de staging a fuité en production\n- Un import de flux produit réintroduit des URLs d'images en HTTP\n- Un plugin WordPress mis à jour écrase la configuration HTTPS du sitemap\n- Une page 404 custom renvoie un canonical HTTP\n\nCe type de régression silencieuse est exactement le genre de problème qu'un outil de monitoring comme Seogard détecte automatiquement — un canonical qui change de protocole, une redirection qui passe de 301 à 302, du mixed content qui réapparaît sur des pages précédemment clean.\n\nIntégrez des [checks SEO dans votre pipeline CI/CD](/blog/automatiser-les-checks-seo-dans-le-ci-cd) pour détecter ces régressions avant qu'elles n'atteignent la production. Un test simple mais efficace :\n\n```javascript\n// Test CI — vérifier que toutes les pages déclarent un canonical HTTPS\nconst { test, expect } = require('@playwright/test');\n\ntest('canonical tags use HTTPS protocol', async ({ page }) => {\n  const urls = [\n    'https://www.example.fr/',\n    'https://www.example.fr/categorie/chaussures-homme',\n    'https://www.example.fr/produit/trail-runner-pro-3',\n    'https://www.example.fr/blog/entretien-chaussures-randonnee',\n  ];\n\n  for (const url of urls) {\n    await page.goto(url);\n    const canonical = await page.$eval(\n      'link[rel=\"canonical\"]',\n      (el) => el.getAttribute('href')\n    );\n    expect(canonical, `Canonical HTTP détecté sur ${url}`).toMatch(/^https:\\/\\//);\n    expect(canonical, `Canonical ne doit pas contenir de double slash dans le path`).not.toMatch(/https:\\/\\/.*\\/\\//);\n  }\n});\n```\n\nExécutez ce test à chaque déploiement. Si un canonical HTTP apparaît, le pipeline échoue et le déploiement est bloqué. C'est un filet de sécurité qui coûte 10 minutes à mettre en place et qui peut éviter des semaines de perte de trafic.\n\nPour un monitoring plus profond et continu sur l'ensemble de vos pages (pas seulement un échantillon CI), les vérifications automatisées de [Chrome DevTools](/blog/chrome-devtools-pour-le-seo-astuces-avancees) en mode headless ou un crawler programmé permettent de scanner quotidiennement votre site à la recherche de régressions de protocole.\n\n---\n\nLa migration HTTP → HTTPS est une opération chirurgicale, pas un toggle. Chaque signal — redirections, canonical, sitemap, liens internes, hreflang, données structurées, HSTS — doit pointer de manière cohérente vers HTTPS. Une seule incohérence suffit à fragmenter vos signaux d'indexation et à prolonger la période de creux. Préparez minutieusement, déployez en une seule fois, et monitorez en continu les semaines qui suivent — c'est dans le suivi que se joue la différence entre une migration à 0 % de perte et une migration à 30 % de perte.\n```","https://seogard.io/blog/migration-http-vers-https-checklist-seo-complete","Migration","2026-04-09T18:02:43.120Z","2026-04-09","Checklist technique pour migrer de HTTP à HTTPS sans perdre de trafic organique. Redirections, HSTS, Search Console, mixed content.","\u003Cp>En 2024, un e-commerce mode de 12 000 pages a perdu 34 % de son trafic organique pendant 11 semaines après une migration HTTPS mal exécutée. Pas à cause du certificat — à cause de redirections en chaîne, de canonical HTTP résiduels dans le \u003Ccode>&#x3C;head>\u003C/code>, et d'un sitemap qui pointait encore vers les anciennes URLs. Tout était techniquement \"en HTTPS\", mais Google continuait d'indexer les versions HTTP.\u003C/p>\n\u003Cp>La migration HTTP vers HTTPS est considérée comme triviale par beaucoup de développeurs. Installer un certificat Let's Encrypt, activer une règle de redirect, terminé. En réalité, c'est une migration d'URLs à part entière — chaque URL HTTP est une ancienne URL qui doit être correctement redirigée, désindexée, et remplacée dans tous les signaux que Google utilise pour évaluer votre site.\u003C/p>\n\u003Ch2>Pré-requis : auditer l'état HTTP avant de toucher quoi que ce soit\u003C/h2>\n\u003Cp>Avant d'activer la moindre redirection, vous avez besoin d'un snapshot complet de votre site en HTTP. Sans cette baseline, vous n'aurez aucun moyen de mesurer l'impact de la migration ni de diagnostiquer les problèmes post-migration.\u003C/p>\n\u003Ch3>Crawl complet du site HTTP\u003C/h3>\n\u003Cp>Lancez un crawl exhaustif avec Screaming Frog (ou Sitebulb) en configurant le crawler sur le protocole \u003Ccode>http://\u003C/code>. Exportez :\u003C/p>\n\u003Cul>\n\u003Cli>La liste complète des URLs crawlées (HTML, images, CSS, JS)\u003C/li>\n\u003Cli>Les canonical déclarés sur chaque page\u003C/li>\n\u003Cli>Les hreflang (si site multilingue — voir \u003Ca href=\"/blog/seo-multilingue-architecture-technique-optimale\">architecture technique multilingue\u003C/a>)\u003C/li>\n\u003Cli>Les liens internes et leur protocole\u003C/li>\n\u003Cli>Les réponses HTTP (200, 301, 404, etc.)\u003C/li>\n\u003C/ul>\n\u003Cp>Ce crawl est votre référence. Vous le comparerez au crawl post-migration pour identifier chaque divergence.\u003C/p>\n\u003Ch3>Snapshot des positions et du trafic\u003C/h3>\n\u003Cp>Dans Google Search Console, exportez les données de performance (clics, impressions, CTR, position moyenne) par page sur les 3 derniers mois. Faites la même chose dans votre outil analytics. Ces données serviront de baseline pour mesurer l'impact.\u003C/p>\n\u003Cp>Si vous suivez des \u003Ca href=\"/blog/mesurer-l-impact-seo-technique-quels-kpis-suivre\">KPIs SEO techniques\u003C/a> avec des dashboards automatisés, prenez un snapshot daté le jour J-1 de la migration.\u003C/p>\n\u003Ch3>Inventaire des signaux externes\u003C/h3>\n\u003Cp>Vos backlinks pointent vers des URLs HTTP. Votre sitemap est en HTTP. Vos profils Google Business, vos réseaux sociaux, vos annuaires — tout référence le protocole HTTP. Listez ces sources. Vous ne pourrez pas toutes les mettre à jour immédiatement, mais vous devez savoir d'où viennent les signaux pour prioriser.\u003C/p>\n\u003Cp>Utilisez Ahrefs ou Majestic pour exporter la liste des backlinks avec le protocole exact (http vs https). Triez par Domain Rating : les backlinks les plus puissants méritent une demande de mise à jour auprès des webmasters.\u003C/p>\n\u003Ch2>Certificat SSL/TLS : choix et installation\u003C/h2>\n\u003Ch3>Quel type de certificat\u003C/h3>\n\u003Cp>Pour la majorité des sites, un certificat DV (Domain Validation) via Let's Encrypt suffit. Google ne fait aucune distinction SEO entre un certificat DV gratuit et un certificat EV à 500 €/an — c'est confirmé dans la \u003Ca href=\"https://developers.google.com/search/docs/crawling-indexing/https\">documentation Google sur HTTPS\u003C/a>.\u003C/p>\n\u003Cp>Si vous gérez un site avec des sous-domaines multiples (shop.example.fr, blog.example.fr, app.example.fr), optez pour un certificat wildcard (\u003Ccode>*.example.fr\u003C/code>) pour simplifier la gestion.\u003C/p>\n\u003Ch3>Installation et vérification\u003C/h3>\n\u003Cp>Sur un serveur Ubuntu avec Nginx et Certbot :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Installation de Certbot pour Nginx\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">sudo\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> apt\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> update\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> &#x26;&#x26; \u003C/span>\u003Cspan style=\"color:#B392F0\">sudo\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> apt\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> install\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> certbot\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> python3-certbot-nginx\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -y\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Génération du certificat (wildcard avec DNS challenge)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">sudo\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> certbot\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> certonly\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --manual\u003C/span>\u003Cspan style=\"color:#79B8FF\"> --preferred-challenges=dns\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  -d\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> example.fr\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -d\u003C/span>\u003Cspan style=\"color:#79B8FF\"> *\u003C/span>\u003Cspan style=\"color:#9ECBFF\">.example.fr\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Vérification de la date d'expiration\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">sudo\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> openssl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> x509\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -in\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> /etc/letsencrypt/live/example.fr/fullchain.pem\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -noout\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -dates\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Test de la configuration SSL\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">openssl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> s_client\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -connect\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> example.fr:443\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -servername\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> example.fr\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Vérifiez que la chaîne de certificats est complète (certificat du serveur + intermédiaire). Une chaîne incomplète provoque des erreurs sur certains clients et peut empêcher Googlebot d'accéder au site. Testez avec \u003Ca href=\"https://www.ssllabs.com/ssltest/\">SSL Labs Server Test\u003C/a> — visez un grade A minimum.\u003C/p>\n\u003Ch3>Configuration TLS dans Nginx\u003C/h3>\n\u003Cp>La configuration TLS impacte à la fois la sécurité et la performance (et donc le crawl). Voici une configuration Nginx production-ready :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">server\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    listen \u003C/span>\u003Cspan style=\"color:#79B8FF\">443\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> ssl http2;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    server_name \u003C/span>\u003Cspan style=\"color:#E1E4E8\">example.fr www.example.fr;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_certificate \u003C/span>\u003Cspan style=\"color:#E1E4E8\">/etc/letsencrypt/live/example.fr/fullchain.pem;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_certificate_key \u003C/span>\u003Cspan style=\"color:#E1E4E8\">/etc/letsencrypt/live/example.fr/privkey.pem;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Protocoles et ciphers modernes\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_protocols \u003C/span>\u003Cspan style=\"color:#E1E4E8\">TLSv1.2 TLSv1.3;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_ciphers \u003C/span>\u003Cspan style=\"color:#E1E4E8\">ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_prefer_server_ciphers \u003C/span>\u003Cspan style=\"color:#79B8FF\">off\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # OCSP Stapling (réduit la latence du handshake TLS)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_stapling \u003C/span>\u003Cspan style=\"color:#79B8FF\">on\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_stapling_verify \u003C/span>\u003Cspan style=\"color:#79B8FF\">on\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    resolver \u003C/span>\u003Cspan style=\"color:#79B8FF\">1.1.1.1\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 8.8.8.8\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> valid=300s;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Session caching\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_session_cache \u003C/span>\u003Cspan style=\"color:#E1E4E8\">shared:SSL:10m;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_session_timeout \u003C/span>\u003Cspan style=\"color:#79B8FF\">1d\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ssl_session_tickets \u003C/span>\u003Cspan style=\"color:#79B8FF\">off\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # HSTS (à activer APRÈS validation complète — voir section dédiée)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # add_header Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\" always;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    root \u003C/span>\u003Cspan style=\"color:#E1E4E8\">/var/www/example.fr;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    index \u003C/span>\u003Cspan style=\"color:#E1E4E8\">index.html;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Point critique : ne commentez pas le HSTS par défaut. Activez-le uniquement après avoir validé que tout fonctionne en HTTPS. Un HSTS mal configuré avec \u003Ccode>includeSubDomains\u003C/code> sur un sous-domaine qui n'a pas de certificat rend ce sous-domaine totalement inaccessible.\u003C/p>\n\u003Ch2>Redirections : le cœur de la migration\u003C/h2>\n\u003Cp>C'est ici que 80 % des migrations échouent. La redirection HTTP → HTTPS est une migration d'URL. Chaque URL HTTP doit retourner une 301 vers son équivalent HTTPS exact — même path, mêmes query parameters.\u003C/p>\n\u003Ch3>Règle de redirection globale\u003C/h3>\n\u003Cp>Dans Nginx, la redirection doit être gérée dans un bloc \u003Ccode>server\u003C/code> dédié au port 80 :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">server\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    listen \u003C/span>\u003Cspan style=\"color:#79B8FF\">80\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    server_name \u003C/span>\u003Cspan style=\"color:#E1E4E8\">example.fr www.example.fr;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Redirection 301 globale HTTP → HTTPS\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # $request_uri préserve le path ET les query strings\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 301\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> https://$host$request_uri;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Sur Apache, dans le \u003Ccode>.htaccess\u003C/code> ou la configuration du VirtualHost :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#B392F0\">VirtualHost\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> *:80\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ServerName\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> example.fr\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    ServerAlias\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> www.example.fr\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    RewriteEngine\u003C/span>\u003Cspan style=\"color:#B392F0\"> On\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    RewriteCond\u003C/span>\u003Cspan style=\"color:#DBEDFF\"> %{HTTPS}\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> off\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    RewriteRule\u003C/span>\u003Cspan style=\"color:#DBEDFF\"> ^(.*)$\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://%{HTTP_HOST}%{REQUEST_URI}\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [L,R=\u003C/span>\u003Cspan style=\"color:#79B8FF\">301\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;/\u003C/span>\u003Cspan style=\"color:#B392F0\">VirtualHost\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3>Les erreurs classiques qui détruisent le trafic\u003C/h3>\n\u003Cp>\u003Cstrong>Chaînes de redirections.\u003C/strong> Le scénario le plus fréquent : \u003Ccode>http://example.fr\u003C/code> → \u003Ccode>https://example.fr\u003C/code> → \u003Ccode>https://www.example.fr\u003C/code>. Deux redirections en chaîne. Googlebot les suit, mais chaque hop dilue le PageRank transmis et ralentit le crawl. Si vous gérez aussi la migration www vers non-www (ou l'inverse), faites une seule redirection directe :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># MAUVAIS : chaîne de redirections\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">server\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    listen \u003C/span>\u003Cspan style=\"color:#79B8FF\">80\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    server_name \u003C/span>\u003Cspan style=\"color:#E1E4E8\">example.fr;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 301\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> https://example.fr$request_uri;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Puis un autre bloc redirige https://example.fr → https://www.example.fr\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># BON : redirection directe vers la destination finale\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">server\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    listen \u003C/span>\u003Cspan style=\"color:#79B8FF\">80\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    server_name \u003C/span>\u003Cspan style=\"color:#E1E4E8\">example.fr www.example.fr;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 301\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> https://www.example.fr$request_uri;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">server\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    listen \u003C/span>\u003Cspan style=\"color:#79B8FF\">443\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> ssl http2;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    server_name \u003C/span>\u003Cspan style=\"color:#E1E4E8\">example.fr;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 301\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> https://www.example.fr$request_uri;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>\u003Cstrong>Redirections en 302 au lieu de 301.\u003C/strong> Certains frameworks (Express.js, Django) redirigent en 302 par défaut. Une 302 indique à Google que la redirection est temporaire — il peut continuer d'indexer l'URL HTTP. Vérifiez explicitement le code de statut dans vos headers.\u003C/p>\n\u003Cp>\u003Cstrong>Query strings perdues.\u003C/strong> Si votre e-commerce utilise des paramètres de filtrage (\u003Ccode>/chaussures?couleur=rouge&#x26;taille=42\u003C/code>), vérifiez que la redirection les préserve. Avec \u003Ccode>$request_uri\u003C/code> dans Nginx, c'est le cas. Avec certaines configurations CDN (Cloudflare Page Rules mal configurées), les query strings peuvent être strippées.\u003C/p>\n\u003Ch3>Vérification post-redirection\u003C/h3>\n\u003Cp>Testez un échantillon d'URLs avec curl pour valider le comportement exact :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Vérifier le code de redirection et la destination\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -I\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> http://www.example.fr/categorie/chaussures-homme?tri=prix-asc\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Résultat attendu :\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># HTTP/1.1 301 Moved Permanently\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Location: https://www.example.fr/categorie/chaussures-homme?tri=prix-asc\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Vérifier qu'il n'y a pas de chaîne\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -ILs\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> http://example.fr/categorie/chaussures-homme\u003C/span>\u003Cspan style=\"color:#F97583\"> 2>&#x26;1\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#B392F0\"> grep\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -E\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"HTTP/|Location:\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Résultat attendu : un seul 301, puis un 200 sur la destination HTTPS finale\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Avec Screaming Frog, recrawlez le site en mode \u003Ccode>http://\u003C/code> et vérifiez que toutes les URLs retournent un 301 vers leur équivalent HTTPS exact. Exportez les redirections en chaîne (Redirect Chains report) et corrigez chaque cas.\u003C/p>\n\u003Ch2>Mixed content : le piège silencieux\u003C/h2>\n\u003Cp>Votre page se charge en HTTPS, mais elle inclut une image en \u003Ccode>http://\u003C/code>, un script en \u003Ccode>http://\u003C/code>, ou une feuille CSS en \u003Ccode>http://\u003C/code>. C'est du mixed content. Les navigateurs modernes bloquent le mixed content actif (scripts, iframes) et affichent des avertissements pour le mixed content passif (images). Google ne considère pas une page comme \"sécurisée\" si elle contient du mixed content actif.\u003C/p>\n\u003Ch3>Identifier le mixed content\u003C/h3>\n\u003Cp>Dans Chrome DevTools (onglet Console ou Security), les erreurs de mixed content apparaissent clairement. Mais pour un site de 12 000 pages, vous ne pouvez pas vérifier manuellement chaque page.\u003C/p>\n\u003Cp>Screaming Frog permet de détecter le mixed content : crawlez le site en HTTPS, puis filtrez les ressources externes chargées en HTTP (Images > Protocol = HTTP, Scripts > Protocol = HTTP, etc.).\u003C/p>\n\u003Cp>Pour une approche plus systématique, utilisez un \u003Ca href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only\">header CSP en mode report-only\u003C/a> :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Dans votre configuration Nginx HTTPS\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">add_header \u003C/span>\u003Cspan style=\"color:#E1E4E8\">Content-Security-Policy-Report-Only\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"default-src https: 'unsafe-inline' 'unsafe-eval'; report-uri /csp-report-endpoint\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    always;\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Puis implémentez un endpoint qui collecte les violations :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Express.js — endpoint de collecte des rapports CSP\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> express\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#B392F0\"> require\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'express'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> app\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#B392F0\"> express\u003C/span>\u003Cspan style=\"color:#E1E4E8\">();\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">app.\u003C/span>\u003Cspan style=\"color:#B392F0\">use\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'/csp-report-endpoint'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, express.\u003C/span>\u003Cspan style=\"color:#B392F0\">json\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({ type: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'application/csp-report'\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> }));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">app.\u003C/span>\u003Cspan style=\"color:#B392F0\">post\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'/csp-report-endpoint'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, (\u003C/span>\u003Cspan style=\"color:#FFAB70\">req\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">res\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> report\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> req.body[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'csp-report'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (report \u003C/span>\u003Cspan style=\"color:#F97583\">&#x26;&#x26;\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> report[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'blocked-uri'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:#F97583\">&#x26;&#x26;\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> report[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'blocked-uri'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">].\u003C/span>\u003Cspan style=\"color:#B392F0\">startsWith\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http:'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    console.\u003C/span>\u003Cspan style=\"color:#B392F0\">log\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">JSON\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      page: report[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'document-uri'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      blockedResource: report[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'blocked-uri'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      directive: report[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'violated-directive'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      timestamp: \u003C/span>\u003Cspan style=\"color:#F97583\">new\u003C/span>\u003Cspan style=\"color:#B392F0\"> Date\u003C/span>\u003Cspan style=\"color:#E1E4E8\">().\u003C/span>\u003Cspan style=\"color:#B392F0\">toISOString\u003C/span>\u003Cspan style=\"color:#E1E4E8\">()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  res.\u003C/span>\u003Cspan style=\"color:#B392F0\">sendStatus\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">204\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">});\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">app.\u003C/span>\u003Cspan style=\"color:#B392F0\">listen\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">3000\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Laissez tourner 48 heures en production. Vous obtiendrez la liste exhaustive de toutes les ressources HTTP chargées sur vos pages HTTPS, classées par page.\u003C/p>\n\u003Ch3>Corriger le mixed content\u003C/h3>\n\u003Cp>Les sources principales de mixed content :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Images hardcodées en base de données\u003C/strong> : les URLs d'images insérées dans le contenu éditorial via un CMS. Requête SQL pour corriger en masse :\u003C/li>\n\u003C/ul>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">-- WordPress : mise à jour des URLs dans le contenu des articles\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">UPDATE\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> wp_posts\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">SET\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> post_content \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> REPLACE\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(post_content, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://cdn.example.fr'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'https://cdn.example.fr'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> post_content \u003C/span>\u003Cspan style=\"color:#F97583\">LIKE\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '%http://cdn.example.fr%'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">-- Idem pour les métadonnées (images à la une, etc.)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">UPDATE\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> wp_postmeta\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">SET\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> meta_value \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> REPLACE\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(meta_value, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'http://cdn.example.fr'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'https://cdn.example.fr'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> meta_value \u003C/span>\u003Cspan style=\"color:#F97583\">LIKE\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '%http://cdn.example.fr%'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cul>\n\u003Cli>\n\u003Cp>\u003Cstrong>Scripts et stylesheets tiers\u003C/strong> : Google Fonts, bibliothèques jQuery hébergées en HTTP, pixels de tracking anciens. Mettez à jour les références ou passez en protocol-relative (\u003Ccode>//fonts.googleapis.com/...\u003C/code>) — bien que l'utilisation explicite de \u003Ccode>https://\u003C/code> soit préférable.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Ressources injectées par JavaScript\u003C/strong> : certains widgets (chat, analytics, pubs) génèrent dynamiquement des URLs HTTP. Vérifiez les scripts tiers et mettez à jour les versions.\u003C/p>\n\u003C/li>\n\u003C/ul>\n\u003Cp>Si vous utilisez un CDN comme Cloudflare, activez \"Automatic HTTPS Rewrites\" pour corriger à la volée le mixed content passif. C'est un filet de sécurité, pas une solution pérenne — corrigez les sources.\u003C/p>\n\u003Ch2>Signaux de référencement : tout mettre à jour\u003C/h2>\n\u003Cp>La redirection seule ne suffit pas. Google utilise de multiples signaux pour déterminer l'URL canonique d'une page. Si ces signaux se contredisent (la redirection dit HTTPS, mais le canonical dit HTTP), Google hésite et peut conserver l'ancienne URL dans l'index pendant des semaines.\u003C/p>\n\u003Ch3>Canonical tags\u003C/h3>\n\u003Cp>Chaque page doit déclarer un canonical en HTTPS :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">&#x3C;!-- AVANT migration -->\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">link\u003C/span>\u003Cspan style=\"color:#B392F0\"> rel\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"canonical\"\u003C/span>\u003Cspan style=\"color:#B392F0\"> href\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"http://www.example.fr/categorie/chaussures-homme\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> />\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">&#x3C;!-- APRÈS migration -->\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#85E89D\">link\u003C/span>\u003Cspan style=\"color:#B392F0\"> rel\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"canonical\"\u003C/span>\u003Cspan style=\"color:#B392F0\"> href\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"https://www.example.fr/categorie/chaussures-homme\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> />\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>C'est le signal le plus oublié. Dans un CMS headless, le canonical est souvent généré dynamiquement côté application. Vérifiez le code source de génération, pas seulement le rendu d'une page.\u003C/p>\n\u003Cp>Si votre site utilise un \u003Ca href=\"/blog/headless-cms-et-seo-avantages-et-risques-techniques\">headless CMS\u003C/a>, le canonical est typiquement construit à partir d'une variable d'environnement (\u003Ccode>SITE_URL\u003C/code> ou équivalent). Changez cette variable de \u003Ccode>http://\u003C/code> en \u003Ccode>https://\u003C/code> et redeployez. Puis validez le rendu côté serveur.\u003C/p>\n\u003Ch3>Sitemap XML\u003C/h3>\n\u003Cp>Générez un nouveau sitemap avec toutes les URLs en HTTPS. Soumettez-le dans Google Search Console. Si votre ancien sitemap est référencé dans le \u003Ccode>robots.txt\u003C/code>, mettez à jour cette référence :\u003C/p>\n\u003Cpre>\u003Ccode># robots.txt — APRÈS migration\nUser-agent: *\nAllow: /\n\nSitemap: https://www.example.fr/sitemap.xml\n\u003C/code>\u003C/pre>\n\u003Cp>Ne supprimez pas l'ancien sitemap HTTP immédiatement. Pendant la phase de transition (4-8 semaines), avoir les deux sitemaps permet à Google de mieux comprendre la correspondance entre anciennes et nouvelles URLs.\u003C/p>\n\u003Ch3>Hreflang (sites multilingues)\u003C/h3>\n\u003Cp>Si vous avez des annotations hreflang, chaque URL référencée doit passer en HTTPS — y compris les URLs vers les versions linguistiques alternatives hébergées sur d'autres domaines ou sous-domaines. Un hreflang qui pointe vers \u003Ccode>http://\u003C/code> alors que la page redirige en HTTPS crée une incohérence qui peut déstabiliser l'indexation multilingue.\u003C/p>\n\u003Ch3>Liens internes\u003C/h3>\n\u003Cp>Même si les redirections 301 fonctionnent, vos liens internes doivent pointer directement vers les URLs HTTPS. Chaque lien interne en HTTP force une redirection, ce qui :\u003C/p>\n\u003Cul>\n\u003Cli>Ajoute 50-200 ms de latence par requête\u003C/li>\n\u003Cli>Consomme inutilement du \u003Ca href=\"/blog/mega-menus-et-seo-attention-au-crawl-budget\">crawl budget\u003C/a>\u003C/li>\n\u003Cli>Transmet un signal ambigu à Google sur le protocole canonique\u003C/li>\n\u003C/ul>\n\u003Cp>Faites un search-and-replace dans votre base de données, vos templates, et vos fichiers de configuration. Puis recrawlez pour vérifier qu'aucun lien interne ne pointe encore vers HTTP.\u003C/p>\n\u003Ch3>Open Graph et données structurées\u003C/h3>\n\u003Cp>Les balises \u003Ccode>og:url\u003C/code>, \u003Ccode>og:image\u003C/code>, et les URLs dans le JSON-LD (schema.org) doivent toutes passer en HTTPS. C'est souvent oublié parce que ces balises n'impactent pas directement le ranking — mais elles impactent l'affichage dans les SERP (rich snippets) et le partage social.\u003C/p>\n\u003Ch2>Google Search Console : propriétés et validation\u003C/h2>\n\u003Cp>Google Search Console traite \u003Ccode>http://\u003C/code> et \u003Ccode>https://\u003C/code> comme deux propriétés distinctes. C'est un point que beaucoup de SEO sous-estiment.\u003C/p>\n\u003Ch3>Créer la propriété HTTPS\u003C/h3>\n\u003Cp>Si vous utilisez une propriété de type \"Domaine\" (vérifiée par DNS), elle couvre automatiquement HTTP et HTTPS. Vous n'avez rien à faire.\u003C/p>\n\u003Cp>Si vous utilisez une propriété de type \"Préfixe d'URL\" (la majorité des cas historiques), vous devez créer une nouvelle propriété \u003Ccode>https://www.example.fr\u003C/code> et la vérifier. Ne supprimez pas l'ancienne propriété \u003Ccode>http://\u003C/code> — conservez-la pour surveiller la décroissance des impressions HTTP et détecter d'éventuels problèmes.\u003C/p>\n\u003Cp>Soumettez le nouveau sitemap HTTPS dans la nouvelle propriété. Consultez les \u003Ca href=\"/blog/google-search-console-les-rapports-que-vous-ignorez\">rapports Search Console que vous ignorez peut-être\u003C/a> pour identifier les signaux de migration réussie.\u003C/p>\n\u003Ch3>Surveiller l'indexation post-migration\u003C/h3>\n\u003Cp>Dans la nouvelle propriété HTTPS, surveillez :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Couverture de l'index\u003C/strong> : les pages HTTPS doivent apparaître comme \"Valides\" progressivement. Les pages HTTP doivent passer en \"Exclues — Page avec redirection\".\u003C/li>\n\u003Cli>\u003Cstrong>Sitemaps\u003C/strong> : vérifiez que le nouveau sitemap est traité et que les URLs sont \"Découvertes\".\u003C/li>\n\u003Cli>\u003Cstrong>Performances\u003C/strong> : comparez les clics/impressions entre les propriétés HTTP et HTTPS sur une fenêtre glissante de 4 semaines.\u003C/li>\n\u003C/ul>\n\u003Cp>La transition complète de l'index prend typiquement 2 à 8 semaines pour un site de 10 000-15 000 pages. Les sites avec un crawl fréquent (médias, e-commerce avec stock en temps réel) migrent plus vite parce que Googlebot passe plus souvent.\u003C/p>\n\u003Cp>Pour automatiser cette surveillance, l'\u003Ca href=\"/blog/search-console-api-automatiser-le-reporting-seo\">API Search Console\u003C/a> permet d'extraire les données de couverture et de performance par propriété, et de déclencher des alertes si les métriques HTTPS ne progressent pas comme attendu.\u003C/p>\n\u003Ch2>HSTS : verrouiller la migration\u003C/h2>\n\u003Cp>Le header HTTP Strict-Transport-Security (HSTS) indique aux navigateurs de ne jamais charger votre site en HTTP, même si l'utilisateur tape \u003Ccode>http://\u003C/code> dans la barre d'adresse. C'est la dernière étape de la migration — et elle est irréversible si vous activez le preload.\u003C/p>\n\u003Ch3>Déploiement progressif du HSTS\u003C/h3>\n\u003Cp>Activez HSTS par paliers pour limiter les risques :\u003C/p>\n\u003Cp>\u003Cstrong>Semaine 1-2 : max-age court, sans includeSubDomains\u003C/strong>\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">add_header \u003C/span>\u003Cspan style=\"color:#E1E4E8\">Strict-Transport-Security \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"max-age=300\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> always;\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>5 minutes. Si quelque chose casse, le navigateur oubliera la directive rapidement.\u003C/p>\n\u003Cp>\u003Cstrong>Semaine 3-4 : augmenter le max-age\u003C/strong>\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">add_header \u003C/span>\u003Cspan style=\"color:#E1E4E8\">Strict-Transport-Security \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"max-age=86400\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> always;\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>24 heures. Surveillez les erreurs.\u003C/p>\n\u003Cp>\u003Cstrong>Semaine 5+ : max-age long avec includeSubDomains\u003C/strong>\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">add_header \u003C/span>\u003Cspan style=\"color:#E1E4E8\">Strict-Transport-Security \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"max-age=63072000; includeSubDomains\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> always;\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>2 ans. C'est la valeur recommandée pour la soumission à la \u003Ca href=\"https://hstspreload.org/\">HSTS preload list\u003C/a>.\u003C/p>\n\u003Cp>\u003Cstrong>Attention critique\u003C/strong> : \u003Ccode>includeSubDomains\u003C/code> signifie que TOUS vos sous-domaines (staging.example.fr, api.example.fr, legacy-app.example.fr) doivent être accessibles en HTTPS avec un certificat valide. Si un sous-domaine interne utilise encore HTTP, il deviendra inaccessible pour tous les navigateurs qui ont reçu le header HSTS. Auditez vos sous-domaines avant d'activer cette directive.\u003C/p>\n\u003Ch3>HSTS Preload\u003C/h3>\n\u003Cp>Le preload inscrit votre domaine dans une liste intégrée aux navigateurs (Chrome, Firefox, Safari, Edge). Même la première visite sera forcée en HTTPS, avant même que le navigateur reçoive le header HSTS. C'est le niveau maximum de protection.\u003C/p>\n\u003Cp>Soumettez votre domaine sur \u003Ca href=\"https://hstspreload.org/\">hstspreload.org\u003C/a> uniquement quand vous êtes absolument certain que le HTTPS fonctionne partout. Le retrait de la preload list prend plusieurs mois.\u003C/p>\n\u003Ch2>Scénario réel : migration d'un e-commerce de 15 000 pages\u003C/h2>\n\u003Cp>Un e-commerce spécialisé en équipement outdoor. 15 200 pages indexées (fiches produits, catégories, pages CMS, blog). Stack : Nginx, PHP-FPM, WordPress + WooCommerce. CDN Cloudflare. 42 000 visites organiques/mois.\u003C/p>\n\u003Ch3>Chronologie\u003C/h3>\n\u003Cp>\u003Cstrong>J-14\u003C/strong> : crawl complet HTTP avec Screaming Frog. Export de 15 200 URLs en 200, 847 canonical tags, 0 hreflang (site monolingue). Identification de 312 liens internes hardcodés en \u003Ccode>http://\u003C/code> dans les descriptions produit (injectées via l'éditeur WYSIWYG).\u003C/p>\n\u003Cp>\u003Cstrong>J-7\u003C/strong> : installation du certificat Let's Encrypt wildcard. Test SSL Labs : grade A. Mise à jour de \u003Ccode>WP_HOME\u003C/code> et \u003Ccode>WP_SITEURL\u003C/code> en \u003Ccode>https://\u003C/code>. Exécution des requêtes SQL pour corriger les URLs dans \u003Ccode>wp_posts\u003C/code> et \u003Ccode>wp_postmeta\u003C/code>. Mise à jour du CDN Cloudflare : Full (Strict) SSL mode + Automatic HTTPS Rewrites activé.\u003C/p>\n\u003Cp>\u003Cstrong>J-1\u003C/strong> : header CSP report-only déployé pendant 24h. Détection de 23 ressources mixtes (images de fournisseurs référencées en HTTP dans des fiches produit importées par flux). Correction manuelle.\u003C/p>\n\u003Cp>\u003Cstrong>J0\u003C/strong> : activation de la redirection 301 HTTP → HTTPS dans Nginx. Déploiement du nouveau \u003Ccode>robots.txt\u003C/code> et \u003Ccode>sitemap.xml\u003C/code> en HTTPS. Création de la propriété HTTPS dans Search Console. Soumission du sitemap. HSTS activé avec \u003Ccode>max-age=300\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>J+1\u003C/strong> : crawl de vérification complet en HTTPS. 15 200 pages en 200. 0 mixed content détecté. 0 chaîne de redirection. Tous les canonical en HTTPS. Liens internes : 99,7 % en HTTPS (8 liens résiduels dans des widgets de sidebar, corrigés dans la journée).\u003C/p>\n\u003Cp>\u003Cstrong>J+3\u003C/strong> : Search Console affiche 4 200 pages HTTPS indexées. Les impressions HTTP commencent à baisser.\u003C/p>\n\u003Cp>\u003Cstrong>J+14\u003C/strong> : 12 800 pages HTTPS indexées. Trafic organique : -8 % vs baseline (fluctuation normale pendant la transition).\u003C/p>\n\u003Cp>\u003Cstrong>J+21\u003C/strong> : HSTS passé à \u003Ccode>max-age=86400\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>J+30\u003C/strong> : 15 100 pages HTTPS indexées (99,3 %). Trafic organique revenu au niveau baseline (-1 %, dans la marge d'erreur).\u003C/p>\n\u003Cp>\u003Cstrong>J+45\u003C/strong> : HSTS passé à \u003Ccode>max-age=63072000; includeSubDomains\u003C/code>. Trafic organique : +3 % vs baseline (corrélation probable avec une légère amélioration du ranking — HTTPS est un signal de classement confirmé par Google, même si son poids est modeste).\u003C/p>\n\u003Cp>\u003Cstrong>J+60\u003C/strong> : soumission au HSTS preload. Propriété HTTP Search Console conservée en lecture seule pour archivage.\u003C/p>\n\u003Ch3>Leçons de ce cas\u003C/h3>\n\u003Cp>Le creux de -8 % à J+14 est normal et documenté. Google doit recrawler et réindexer chaque page dans sa nouvelle version HTTPS. Pendant cette période, certaines pages sont encore indexées en HTTP, d'autres en HTTPS, et les signaux sont fragmentés. La durée du creux dépend directement de la fréquence de crawl de votre site.\u003C/p>\n\u003Cp>La correction des 312 liens internes hardcodés en base de données a été le point le plus chronophage (3 heures de vérification et de requêtes SQL). Sur un site avec un contenu éditorial plus riche (média, blog avec des milliers d'articles), cette étape peut prendre une journée complète.\u003C/p>\n\u003Ch2>Monitoring post-migration et détection de régression\u003C/h2>\n\u003Cp>La migration ne s'arrête pas à J+30. Des régressions peuvent survenir des mois plus tard :\u003C/p>\n\u003Cul>\n\u003Cli>Un développeur ajoute une nouvelle page avec un canonical en HTTP parce que la variable d'environnement de staging a fuité en production\u003C/li>\n\u003Cli>Un import de flux produit réintroduit des URLs d'images en HTTP\u003C/li>\n\u003Cli>Un plugin WordPress mis à jour écrase la configuration HTTPS du sitemap\u003C/li>\n\u003Cli>Une page 404 custom renvoie un canonical HTTP\u003C/li>\n\u003C/ul>\n\u003Cp>Ce type de régression silencieuse est exactement le genre de problème qu'un outil de monitoring comme Seogard détecte automatiquement — un canonical qui change de protocole, une redirection qui passe de 301 à 302, du mixed content qui réapparaît sur des pages précédemment clean.\u003C/p>\n\u003Cp>Intégrez des \u003Ca href=\"/blog/automatiser-les-checks-seo-dans-le-ci-cd\">checks SEO dans votre pipeline CI/CD\u003C/a> pour détecter ces régressions avant qu'elles n'atteignent la production. Un test simple mais efficace :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Test CI — vérifier que toutes les pages déclarent un canonical HTTPS\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> { \u003C/span>\u003Cspan style=\"color:#79B8FF\">test\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">expect\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> } \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#B392F0\"> require\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'@playwright/test'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">test\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'canonical tags use HTTPS protocol'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#F97583\">async\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> ({ \u003C/span>\u003Cspan style=\"color:#FFAB70\">page\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> }) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> urls\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'https://www.example.fr/'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'https://www.example.fr/categorie/chaussures-homme'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'https://www.example.fr/produit/trail-runner-pro-3'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'https://www.example.fr/blog/entretien-chaussures-randonnee'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  ];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> url\u003C/span>\u003Cspan style=\"color:#F97583\"> of\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> urls) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> page.\u003C/span>\u003Cspan style=\"color:#B392F0\">goto\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(url);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> canonical\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> page.\u003C/span>\u003Cspan style=\"color:#B392F0\">$eval\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'link[rel=\"canonical\"]'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      (\u003C/span>\u003Cspan style=\"color:#FFAB70\">el\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> el.\u003C/span>\u003Cspan style=\"color:#B392F0\">getAttribute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'href'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">    expect\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(canonical, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">`Canonical HTTP détecté sur ${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">url\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">).\u003C/span>\u003Cspan style=\"color:#B392F0\">toMatch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#F97583\">^\u003C/span>\u003Cspan style=\"color:#DBEDFF\">https:\u003C/span>\u003Cspan style=\"color:#85E89D;font-weight:bold\">\\/\\/\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">    expect\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(canonical, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">`Canonical ne doit pas contenir de double slash dans le path`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">).not.\u003C/span>\u003Cspan style=\"color:#B392F0\">toMatch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#DBEDFF\">https:\u003C/span>\u003Cspan style=\"color:#85E89D;font-weight:bold\">\\/\\/\u003C/span>\u003Cspan style=\"color:#79B8FF\">.\u003C/span>\u003Cspan style=\"color:#F97583\">*\u003C/span>\u003Cspan style=\"color:#85E89D;font-weight:bold\">\\/\\/\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">});\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Exécutez ce test à chaque déploiement. Si un canonical HTTP apparaît, le pipeline échoue et le déploiement est bloqué. C'est un filet de sécurité qui coûte 10 minutes à mettre en place et qui peut éviter des semaines de perte de trafic.\u003C/p>\n\u003Cp>Pour un monitoring plus profond et continu sur l'ensemble de vos pages (pas seulement un échantillon CI), les vérifications automatisées de \u003Ca href=\"/blog/chrome-devtools-pour-le-seo-astuces-avancees\">Chrome DevTools\u003C/a> en mode headless ou un crawler programmé permettent de scanner quotidiennement votre site à la recherche de régressions de protocole.\u003C/p>\n\u003Chr>\n\u003Cp>La migration HTTP → HTTPS est une opération chirurgicale, pas un toggle. Chaque signal — redirections, canonical, sitemap, liens internes, hreflang, données structurées, HSTS — doit pointer de manière cohérente vers HTTPS. Une seule incohérence suffit à fragmenter vos signaux d'indexation et à prolonger la période de creux. Préparez minutieusement, déployez en une seule fois, et monitorez en continu les semaines qui suivent — c'est dans le suivi que se joue la différence entre une migration à 0 % de perte et une migration à 30 % de perte.\u003C/p>\n\u003Cpre>\u003Ccode>\u003C/code>\u003C/pre>",null,14,[18,19,20,21],"https","migration","redirections","seo","Migration HTTP vers HTTPS : checklist SEO complète","Thu Apr 09 2026 18:02:43 GMT+0000 (Coordinated Universal Time)",[]]