[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$flbY6Bd94TUjQALQuB_64cXCA2TA_JVGoxGXcR5VgNd4":3,"$fJOQF_oK6T9kFB7RHXcR4O0o2I-tus5JW48U7cNjmem4":25},{"_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":23,"updatedAt":24},"6a001f8baa6b273b0cfd7642","google-core-update-reshuffles-winners-ai-search-expands-links-seo-pulse-via-sejournal-mattgsouthern",0,"Equipe Seogard","Un site e-commerce de 22 000 pages qui perd 34 % de son trafic organique en 11 jours. Un média de niche qui en gagne 45 %. Le dernier Core Update de Google ne s'est pas contenté de reclasser quelques requêtes — il a redessiné la carte de la visibilité organique pendant que, en parallèle, AI Search élargit discrètement le nombre de liens affichés dans ses réponses. Ces deux mouvements simultanés créent un changement de paradigme que la plupart des équipes SEO n'ont pas encore pleinement cartographié.\n\n## Anatomie du Core Update : ce que les données Amsive révèlent vraiment\n\nL'analyse publiée par Amsive Digital sur les gagnants et perdants du Core Update de mars-mai 2025 confirme une tendance amorcée lors des updates précédents : Google continue de pénaliser les sites qui agrègent du contenu sans apport éditorial propre, et récompense les sources primaires disposant de signaux d'expertise vérifiables.\n\nLe pattern est plus granulaire qu'un simple « content quality check ». Les sites qui ont progressé partagent trois caractéristiques techniques mesurables :\n\n- **Profondeur d'entités** : des pages qui couvrent un sujet avec un maillage sémantique dense entre entités liées, plutôt qu'un survol keyword-centric.\n- **Fraîcheur structurée** : des dates de mise à jour cohérentes entre le contenu visible, le `dateModified` en structured data et le `Last-Modified` header HTTP.\n- **Signaux d'autorité thématique** : des backlinks provenant de domaines topiquement proches, pas de link profiles « flat » accumulant des liens de domaines sans rapport.\n\nLes perdants, eux, présentent un schéma récurrent : des pages à faible valeur ajoutée qui rankaient grâce à l'autorité de domaine seule. Google a visiblement recalibré le poids du domain authority par rapport aux signaux page-level et entité-level.\n\nCe [déplacement de visibilité loin des agrégateurs](/blog/google-s-march-core-update-shifted-visibility-away-from-aggregators-via-sejournal-mattgsouthern) n'est pas nouveau, mais l'amplitude de ce Core Update est significative.\n\n### Mesurer l'impact avec précision : au-delà de la Search Console\n\nLa Search Console reste l'outil de base, mais ses données sont agrégées et retardées de 48-72h. Pour un diagnostic en temps réel lors d'un Core Update, vous devez croiser plusieurs sources.\n\nVoici un script Python qui interroge l'API Search Console pour extraire les variations de position query par query sur une fenêtre de 14 jours avant/après le début du rollout :\n\n```python\nfrom google.oauth2 import service_account\nfrom googleapiclient.discovery import build\nimport pandas as pd\n\nSCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']\nSERVICE_ACCOUNT_FILE = 'credentials.json'\nSITE_URL = 'https://www.votresite.fr/'\n\ncredentials = service_account.Credentials.from_service_account_file(\n    SERVICE_ACCOUNT_FILE, scopes=SCOPES)\nservice = build('searchconsole', 'v1', credentials=credentials)\n\ndef get_query_data(start_date, end_date):\n    request = {\n        'startDate': start_date,\n        'endDate': end_date,\n        'dimensions': ['query', 'page'],\n        'rowLimit': 25000,\n        'dimensionFilterGroups': [{\n            'filters': [{\n                'dimension': 'country',\n                'expression': 'fra'\n            }]\n        }]\n    }\n    response = service.searchanalytics().query(\n        siteUrl=SITE_URL, body=request).execute()\n    return pd.DataFrame(response.get('rows', []))\n\n# 14 jours avant le rollout vs 14 jours après\ndf_before = get_query_data('2025-04-20', '2025-05-03')\ndf_after = get_query_data('2025-05-04', '2025-05-17')\n\n# Extraction des métriques par query\nfor df in [df_before, df_after]:\n    df['query'] = df['keys'].apply(lambda x: x[0])\n    df['page'] = df['keys'].apply(lambda x: x[1])\n\nmerged = df_before.merge(df_after, on=['query', 'page'],\n                         suffixes=('_before', '_after'))\nmerged['position_delta'] = merged['position_after'] - merged['position_before']\nmerged['clicks_delta_pct'] = (\n    (merged['clicks_after'] - merged['clicks_before'])\n    / merged['clicks_before'].replace(0, 1) * 100\n)\n\n# Top losers : pages qui ont perdu le plus de positions\nlosers = merged.nlargest(50, 'position_delta')\nlosers.to_csv('core_update_losers.csv', index=False)\n\n# Top winners\nwinners = merged.nsmallest(50, 'position_delta')\nwinners.to_csv('core_update_winners.csv', index=False)\n```\n\nCe script vous donne un fichier CSV exploitable en 5 minutes. L'étape suivante consiste à regrouper les losers par template de page (catégorie, fiche produit, blog, etc.) pour identifier si le Core Update cible un type de contenu spécifique plutôt que le site dans son ensemble.\n\nLe piège classique : conclure que « tout le site a été pénalisé » alors que seules les pages de listing sans contenu éditorial ont reculé. Cette granularité change radicalement le plan d'action.\n\n## AI Search étend ses liens : les implications techniques\n\nGoogle a ajouté des subscription labels et des inline links dans AI Search (AI Overviews et AI Mode). Concrètement, les réponses générées par l'IA affichent désormais davantage de liens vers des sources, y compris des indications sur le contenu paywall.\n\nCe changement a deux implications majeures que la plupart des analyses superficielles ignorent.\n\n### Plus de liens, pas plus de click data\n\nPremier problème : [Google étend les liens dans AI Search sans fournir de nouvelles données de clic](/blog/google-expands-ai-search-links-without-new-click-data-via-sejournal-mattgsouthern) dans la Search Console. Vous pouvez apparaître comme source citée dans une AI Overview sans que cette impression ou ce clic apparaisse dans vos rapports.\n\nCela crée un angle mort analytique considérable. Si votre site est cité dans 30 % des AI Overviews de votre verticale mais que vous ne voyez aucune donnée correspondante, votre perception de la performance SEO est biaisée.\n\nPour commencer à tracer ces interactions côté serveur, vous pouvez identifier les referrers spécifiques aux clics provenant d'AI Overviews. Google utilise des paramètres UTM et des referrer paths distincts. Voici une configuration Nginx pour logger ces hits séparément :\n\n```nginx\n# /etc/nginx/conf.d/ai-search-tracking.conf\n\n# Map pour identifier les referrers AI Search de Google\nmap $http_referer $is_ai_search_referrer {\n    default 0;\n    \"~*google\\.com/search.*udm=14\"  1;  # AI Mode\n    \"~*google\\.com/search.*sourceid=ai\" 1;\n    \"~*google\\.com.*ai-overview\" 1;\n}\n\n# Map pour identifier l'user-agent Google Extended (AI features)\nmap $http_user_agent $is_google_extended {\n    default 0;\n    \"~*Google-Extended\" 1;\n}\n\n# Log format dédié avec le flag AI search\nlog_format ai_search_log '$remote_addr - $time_iso8601 '\n    '\"$request_uri\" $status '\n    '\"$http_referer\" '\n    '\"$http_user_agent\" '\n    'ai_ref=$is_ai_search_referrer '\n    'g_ext=$is_google_extended';\n\nserver {\n    # ... votre config existante ...\n\n    # Log séparé pour le trafic AI search\n    access_log /var/log/nginx/ai_search_access.log ai_search_log\n        if=$is_ai_search_referrer;\n\n    # Log séparé pour les crawls Google Extended\n    access_log /var/log/nginx/google_extended.log ai_search_log\n        if=$is_google_extended;\n}\n```\n\nCe n'est pas parfait — Google ne documente pas publiquement tous les patterns de referrer pour AI Search, et ils changent régulièrement. Mais c'est mieux que l'angle mort total. Croisez ces logs serveur avec vos données Search Console pour estimer le delta.\n\n### Les subscription labels changent la donne pour les sites paywall\n\nL'ajout de labels « subscription » dans AI Search est un signal fort : Google indique explicitement aux utilisateurs que le contenu source est payant. Pour les éditeurs qui dépendent d'un modèle freemium/paywall, cela change l'équation.\n\nLe risque : l'utilisateur obtient la réponse via l'AI Overview et ne clique jamais sur la source payante, le label « subscription » agissant comme un repoussoir supplémentaire.\n\nL'opportunité : si Google labellise votre contenu comme « subscription », c'est une reconnaissance implicite de sa valeur en tant que source primaire. Et [les signaux qui définissent la visibilité en AI Search](/blog/4-signals-that-now-define-visibility-in-ai-search) montrent que les sources perçues comme autoritaires et originales sont davantage citées.\n\nPour les sites avec paywall, la config `structured data` des articles doit être irréprochable :\n\n```html\n\u003Cscript type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"NewsArticle\",\n  \"headline\": \"Analyse exclusive du marché des semi-conducteurs Q2 2025\",\n  \"datePublished\": \"2025-05-08T09:00:00+02:00\",\n  \"dateModified\": \"2025-05-09T14:30:00+02:00\",\n  \"author\": {\n    \"@type\": \"Person\",\n    \"name\": \"Marie Dupont\",\n    \"url\": \"https://www.votremedia.fr/auteurs/marie-dupont\",\n    \"jobTitle\": \"Analyste senior semi-conducteurs\",\n    \"sameAs\": [\n      \"https://www.linkedin.com/in/mariedupont-analyst\",\n      \"https://twitter.com/mdupont_semicon\"\n    ]\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"Votre Média Tech\",\n    \"logo\": {\n      \"@type\": \"ImageObject\",\n      \"url\": \"https://www.votremedia.fr/logo.png\"\n    }\n  },\n  \"isAccessibleForFree\": false,\n  \"hasPart\": {\n    \"@type\": \"WebPageElement\",\n    \"isAccessibleForFree\": false,\n    \"cssSelector\": \".article-body-premium\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https://www.votremedia.fr/analyse-semiconducteurs-q2-2025\"\n  }\n}\n\u003C/script>\n```\n\nLe champ `isAccessibleForFree: false` couplé au `hasPart` avec `cssSelector` permet à Google de comprendre précisément quelle portion du contenu est derrière le paywall. Sans cette déclaration, Google peut mal interpréter votre modèle et soit ignorer votre contenu, soit le traiter comme du cloaking si le markup ne correspond pas à la réalité visible par Googlebot.\n\nRéférence : la [documentation officielle de Google sur les contenus paywall et le structured data](https://developers.google.com/search/docs/appearance/structured-data/paywalled-content) détaille les exigences techniques.\n\n## Mueller sur le « vibe coding » : signal faible, impact structurel\n\nJohn Mueller a commenté le phénomène du « vibe coding » — la pratique de générer du code entier via des LLM sans le relire en détail. Sa position est mesurée mais le message est clair : Google ne pénalise pas le code généré par IA en soi, mais les conséquences techniques d'un code mal maîtrisé impactent le SEO indirectement.\n\nLe lien avec le Core Update est direct. Voici un scénario réel que nous observons de plus en plus.\n\n### Scénario : un SaaS de 8 000 pages génère son frontend avec un LLM\n\nUn SaaS B2B a migré son marketing site de Gatsby vers Next.js en utilisant massivement Cursor + Claude pour générer les composants. Le résultat visuel était correct. Le résultat SEO, catastrophique :\n\n**Avant la migration** : 8 200 pages indexées, position moyenne 12.4, 45 000 clics/mois.\n\n**3 semaines après** : 3 100 pages indexées, position moyenne 28.7, 11 000 clics/mois.\n\nLes causes identifiées via un crawl Screaming Frog + analyse des logs serveur :\n\n1. **Le LLM a généré du client-side rendering par défaut** pour 60 % des pages. Les composants utilisaient `useEffect` pour fetcher les données, rendant le contenu invisible au crawl initial. Le SSR était configuré dans `next.config.js` mais le code généré court-circuitait le mécanisme.\n\n2. **Les balises canonical auto-générées pointaient vers des URLs avec des paramètres de session**. Le template généré par l'IA incluait un `useRouter` qui ajoutait des query params au canonical.\n\n3. **Les liens internes utilisaient un composant custom `\u003CLink>` qui effectuait une navigation client-side sans `\u003Ca href>`**, rendant le maillage interne invisible pour Googlebot.\n\nLe problème n'est pas que le code est généré par IA. Le problème est que personne n'a audité les outputs avec un regard SEO technique. C'est exactement le type de [régression que le quality threshold de Google cible](/blog/google-s-quality-threshold-is-quietly-killing-scaled-ai-content-via-sejournal-taylordanrw) — pas une pénalité manuelle, mais une dégradation technique qui fait naturellement sortir les pages de l'index.\n\nPour détecter ce type de régression avant que Google ne la sanctionne, un monitoring continu des meta tags, du statut SSR et des canonicals est indispensable. Un outil comme Seogard détecte ces cassures dès qu'elles apparaissent en production, avant que l'impact ne se propage dans les SERPs.\n\nCommande Screaming Frog pour valider le rendu JavaScript de vos pages critiques :\n\n```bash\n# Crawl en mode JavaScript rendering avec Screaming Frog CLI\n# Vérifie que le contenu est bien rendu server-side\nscreaming-frog-cli \\\n  --crawl \"https://www.votresaas.com/features\" \\\n  --headless \\\n  --config js-rendering-config.seospiderconfig \\\n  --export-tabs \"Internal:All,Response Codes:All\" \\\n  --output-folder /tmp/sf-audit/ \\\n  --max-crawl-depth 4 \\\n  --limit-crawl-total 5000 \\\n  --render-js true \\\n  --js-rendering-wait 8000\n\n# Puis comparer le HTML initial vs le HTML rendu\n# pour identifier les pages où le contenu n'apparaît qu'après JS execution\ndiff \u003C(curl -s \"https://www.votresaas.com/features\" | htmlq 'h1,h2,p' --text) \\\n     \u003C(node -e \"\n       const puppeteer = require('puppeteer');\n       (async () => {\n         const browser = await puppeteer.launch({headless: 'new'});\n         const page = await browser.newPage();\n         await page.goto('https://www.votresaas.com/features', {waitUntil: 'networkidle0'});\n         const text = await page.evaluate(() => {\n           return [...document.querySelectorAll('h1,h2,p')].map(el => el.textContent).join('\\n');\n         });\n         console.log(text);\n         await browser.close();\n       })();\n     \")\n```\n\nSi le `diff` montre du contenu manquant dans le `curl` (HTML statique) mais présent dans le rendu Puppeteer, vos pages ont un problème de SSR. Google peut éventuellement exécuter le JavaScript, mais le délai de rendering et le crawl budget consommé jouent contre vous, surtout lors d'un Core Update où Google réévalue massivement la qualité.\n\n## Preferred Sources : Google officialise la hiérarchie des sources\n\nLa feature Preferred Sources, mentionnée par Mueller et observable dans les résultats récents, permet à Google de prioriser certaines sources pour des types de requêtes spécifiques. Ce n'est pas un programme opt-in — c'est un signal algorithmique basé sur l'historique de fiabilité, la cohérence thématique et l'autorité perçue d'un domaine sur un topic cluster donné.\n\nLes implications techniques sont profondes. Google ne regarde plus uniquement la pertinence page-level pour une requête donnée. Il évalue si votre domaine est une « source préférée » pour une thématique entière.\n\n### Comment auditer votre statut de source sur un topic\n\nL'approche la plus fiable consiste à analyser votre couverture thématique dans la Search Console et la comparer à celle de vos concurrents qui gagnent en visibilité.\n\nÉtape 1 : exportez toutes vos requêtes sur 3 mois et clusterisez-les par entité principale (outil : Python + un modèle d'embeddings, ou plus simplement, un clustering par n-grams partagés).\n\nÉtape 2 : pour chaque cluster, calculez votre « taux de couverture » — le ratio entre le nombre de requêtes pour lesquelles vous avez au moins une page en top 20 et le nombre total de requêtes dans le cluster.\n\nÉtape 3 : identifiez les clusters où votre couverture est inférieure à 40 %. Ce sont vos « trous topiques » — les zones où Google ne vous considère pas comme une source préférée.\n\nCe travail rejoint directement l'approche de [SEO programmatique sémantique](/blog/a-blueprint-for-semantic-programmatic-seo) : combler les trous topiques avec du contenu structuré qui couvre les entités manquantes dans votre maillage.\n\nL'erreur serait de publier 200 articles thin pour couvrir ces gaps. Le [quality threshold de Google élimine précisément ce type d'approche](/blog/google-s-quality-threshold-is-quietly-killing-scaled-ai-content-at-ranking-via-sejournal-taylordanrw). Il faut moins de pages, mais plus denses, avec des données propriétaires ou un angle éditorial que vos concurrents ne couvrent pas.\n\n## Le lien entre Core Update et AI Search : convergence des signaux\n\nLa simultanéité du Core Update et de l'expansion des liens AI Search n'est pas une coïncidence. Google aligne progressivement les critères de ranking organique classique avec les critères de citation dans AI Overviews.\n\nLes sites qui gagnent dans le Core Update sont souvent les mêmes qui voient leur citation rate augmenter dans AI Search. Pourquoi ? Parce que les signaux convergent :\n\n- **Source primaire vs agrégateur** : AI Search cite prioritairement la source originale d'une information. Le Core Update déclasse les agrégateurs qui reformulent sans ajouter de valeur. Même logique.\n- **Structured data cohérent** : les AI Overviews s'appuient sur le knowledge graph et le structured data pour sélectionner les sources. Les sites dont le markup est cassé ou incohérent sont invisibles dans les deux canaux.\n- **Autorité thématique** : le concept de Preferred Sources dans le ranking classique et la sélection de sources dans AI Search reposent sur le même graphe d'autorité topique.\n\nSi vous travaillez votre [visibilité en AI Search](/blog/500m-ai-searches-later-how-to-actually-improve-ai-search-visibility-citations-via-sejournal-mattgsouthern), vous travaillez aussi votre résilience aux Core Updates. Et inversement.\n\nL'observation de [comment les modèles IA comprennent votre marque](/blog/how-ai-models-understand-your-brand) éclaire un point souvent négligé : la représentation de votre site dans les embeddings des LLM influence à la fois votre citation dans AI Search et la perception de votre autorité par les systèmes de ranking de Google, qui intègrent de plus en plus de composants basés sur des modèles de langage.\n\n## Plan d'action post-Core Update : checklist technique\n\nPlutôt qu'une liste générique, voici un workflow séquentiel adapté à un site de 5 000 à 50 000 pages qui vient de subir un Core Update.\n\n**Phase 1 — Diagnostic (J+0 à J+3)**\n\nIdentifiez le type de pages impactées. Utilisez le script Search Console ci-dessus. Regroupez les résultats par template. Si 80 % des pertes viennent de vos pages de listing, le problème n'est pas votre blog.\n\n**Phase 2 — Audit technique ciblé (J+3 à J+7)**\n\nCrawlez uniquement les templates impactés avec Screaming Frog. Vérifiez :\n- Cohérence canonical (self-referencing, pas de chaînes)\n- Présence et validité du structured data sur chaque page\n- Ratio contenu unique vs contenu dupliqué (surtout pour les pages de catégorie e-commerce qui n'affichent que des extraits produits)\n- Headers HTTP : `Last-Modified` cohérent avec `dateModified` du structured data\n\n**Phase 3 — Correction et consolidation (J+7 à J+30)**\n\nPriorisez les corrections par impact potentiel. Les pages qui étaient en position 5-15 avant l'update et qui sont tombées en 20-40 sont les plus récupérables. Les pages qui étaient en position 30+ et qui sont tombées en 50+ ne valent probablement pas l'effort — considérez leur suppression ou leur consolidation.\n\nPour la consolidation, vérifiez que vos redirections ne créent pas de chaînes. Un classique post-Core Update : fusionner 3 pages thin en 1 page dense, mais oublier de mettre à jour les liens internes qui pointent encore vers les anciennes URLs, créant des chaînes de redirects 301 qui diluent le link equity.\n\n**Phase 4 — Monitoring continu (J+30+)**\n\nLe prochain Core Update arrivera. La question n'est pas si, mais quand. La capacité à détecter une régression technique le jour où elle apparaît — une meta title qui disparaît après un déploiement, un canonical qui se casse, un SSR qui tombe — fait la différence entre un site qui oscille d'update en update et un site qui progresse régulièrement. C'est exactement ce que Seogard automatise : un monitoring continu qui vous alerte avant que Googlebot ne constate les dégâts.\n\n## Ce qu'il faut retenir\n\nCe Core Update confirme la direction prise par Google depuis deux ans : les sources primaires, thématiquement cohérentes et techniquement irréprochables gagnent du terrain. Les agrégateurs et les sites qui comptent sur leur autorité de domaine pour ranker du contenu superficiel reculent. En parallèle, [l'expansion des liens dans AI Search](/blog/google-updates-links-within-ai-overviews-ai-mode) crée un nouveau canal de visibilité — mais aussi un nouvel angle mort analytique que vous devez combler côté serveur. L'alignement de votre stratégie SEO classique avec votre visibilité en AI Search n'est plus optionnel : c'est le même jeu, joué sur deux tableaux.\n```","https://seogard.io/blog/google-core-update-reshuffles-winners-ai-search-expands-links-seo-pulse-via-sejournal-mattgsouthern","Actualités SEO","2026-05-10T06:02:51.605Z","2026-05-10","Décryptage technique du Core Update Google, des liens AI Search étendus et de leurs impacts concrets sur le SEO de sites à forte volumétrie.","\u003Cp>Un site e-commerce de 22 000 pages qui perd 34 % de son trafic organique en 11 jours. Un média de niche qui en gagne 45 %. Le dernier Core Update de Google ne s'est pas contenté de reclasser quelques requêtes — il a redessiné la carte de la visibilité organique pendant que, en parallèle, AI Search élargit discrètement le nombre de liens affichés dans ses réponses. Ces deux mouvements simultanés créent un changement de paradigme que la plupart des équipes SEO n'ont pas encore pleinement cartographié.\u003C/p>\n\u003Ch2>Anatomie du Core Update : ce que les données Amsive révèlent vraiment\u003C/h2>\n\u003Cp>L'analyse publiée par Amsive Digital sur les gagnants et perdants du Core Update de mars-mai 2025 confirme une tendance amorcée lors des updates précédents : Google continue de pénaliser les sites qui agrègent du contenu sans apport éditorial propre, et récompense les sources primaires disposant de signaux d'expertise vérifiables.\u003C/p>\n\u003Cp>Le pattern est plus granulaire qu'un simple « content quality check ». Les sites qui ont progressé partagent trois caractéristiques techniques mesurables :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Profondeur d'entités\u003C/strong> : des pages qui couvrent un sujet avec un maillage sémantique dense entre entités liées, plutôt qu'un survol keyword-centric.\u003C/li>\n\u003Cli>\u003Cstrong>Fraîcheur structurée\u003C/strong> : des dates de mise à jour cohérentes entre le contenu visible, le \u003Ccode>dateModified\u003C/code> en structured data et le \u003Ccode>Last-Modified\u003C/code> header HTTP.\u003C/li>\n\u003Cli>\u003Cstrong>Signaux d'autorité thématique\u003C/strong> : des backlinks provenant de domaines topiquement proches, pas de link profiles « flat » accumulant des liens de domaines sans rapport.\u003C/li>\n\u003C/ul>\n\u003Cp>Les perdants, eux, présentent un schéma récurrent : des pages à faible valeur ajoutée qui rankaient grâce à l'autorité de domaine seule. Google a visiblement recalibré le poids du domain authority par rapport aux signaux page-level et entité-level.\u003C/p>\n\u003Cp>Ce \u003Ca href=\"/blog/google-s-march-core-update-shifted-visibility-away-from-aggregators-via-sejournal-mattgsouthern\">déplacement de visibilité loin des agrégateurs\u003C/a> n'est pas nouveau, mais l'amplitude de ce Core Update est significative.\u003C/p>\n\u003Ch3>Mesurer l'impact avec précision : au-delà de la Search Console\u003C/h3>\n\u003Cp>La Search Console reste l'outil de base, mais ses données sont agrégées et retardées de 48-72h. Pour un diagnostic en temps réel lors d'un Core Update, vous devez croiser plusieurs sources.\u003C/p>\n\u003Cp>Voici un script Python qui interroge l'API Search Console pour extraire les variations de position query par query sur une fenêtre de 14 jours avant/après le début du rollout :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> google.oauth2 \u003C/span>\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> service_account\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> googleapiclient.discovery \u003C/span>\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> build\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> pandas \u003C/span>\u003Cspan style=\"color:#F97583\">as\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> pd\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">SCOPES\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'https://www.googleapis.com/auth/webmasters.readonly'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">SERVICE_ACCOUNT_FILE\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'credentials.json'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">SITE_URL\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'https://www.votresite.fr/'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">credentials \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> service_account.Credentials.from_service_account_file(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">    SERVICE_ACCOUNT_FILE\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">scopes\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\">SCOPES\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">service \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> build(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'searchconsole'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'v1'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">credentials\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">credentials)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">def\u003C/span>\u003Cspan style=\"color:#B392F0\"> get_query_data\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(start_date, end_date):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    request \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'startDate'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: start_date,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'endDate'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: end_date,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'dimensions'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'query'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'page'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'rowLimit'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">25000\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'dimensionFilterGroups'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">            'filters'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">                'dimension'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'country'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">                'expression'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'fra'\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\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    response \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> service.searchanalytics().query(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">        siteUrl\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\">SITE_URL\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">body\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">request).execute()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> pd.DataFrame(response.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'rows'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, []))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># 14 jours avant le rollout vs 14 jours après\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">df_before \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> get_query_data(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'2025-04-20'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'2025-05-03'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">df_after \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> get_query_data(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'2025-05-04'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'2025-05-17'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Extraction des métriques par query\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> df \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [df_before, df_after]:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    df[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'query'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> df[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'keys'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">].apply(\u003C/span>\u003Cspan style=\"color:#F97583\">lambda\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> x: x[\u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">])\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    df[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'page'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> df[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'keys'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">].apply(\u003C/span>\u003Cspan style=\"color:#F97583\">lambda\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> x: x[\u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">])\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">merged \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> df_before.merge(df_after, \u003C/span>\u003Cspan style=\"color:#FFAB70\">on\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'query'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'page'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">                         suffixes\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'_before'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'_after'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">merged[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'position_delta'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> merged[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'position_after'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:#F97583\">-\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> merged[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'position_before'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">merged[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'clicks_delta_pct'\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:#E1E4E8\">    (merged[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'clicks_after'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:#F97583\">-\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> merged[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'clicks_before'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">])\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    /\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> merged[\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'clicks_before'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">].replace(\u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">*\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 100\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\"># Top losers : pages qui ont perdu le plus de positions\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">losers \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> merged.nlargest(\u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'position_delta'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">losers.to_csv(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'core_update_losers.csv'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">index\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\">False\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Top winners\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">winners \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> merged.nsmallest(\u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'position_delta'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">winners.to_csv(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'core_update_winners.csv'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">index\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\">False\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ce script vous donne un fichier CSV exploitable en 5 minutes. L'étape suivante consiste à regrouper les losers par template de page (catégorie, fiche produit, blog, etc.) pour identifier si le Core Update cible un type de contenu spécifique plutôt que le site dans son ensemble.\u003C/p>\n\u003Cp>Le piège classique : conclure que « tout le site a été pénalisé » alors que seules les pages de listing sans contenu éditorial ont reculé. Cette granularité change radicalement le plan d'action.\u003C/p>\n\u003Ch2>AI Search étend ses liens : les implications techniques\u003C/h2>\n\u003Cp>Google a ajouté des subscription labels et des inline links dans AI Search (AI Overviews et AI Mode). Concrètement, les réponses générées par l'IA affichent désormais davantage de liens vers des sources, y compris des indications sur le contenu paywall.\u003C/p>\n\u003Cp>Ce changement a deux implications majeures que la plupart des analyses superficielles ignorent.\u003C/p>\n\u003Ch3>Plus de liens, pas plus de click data\u003C/h3>\n\u003Cp>Premier problème : \u003Ca href=\"/blog/google-expands-ai-search-links-without-new-click-data-via-sejournal-mattgsouthern\">Google étend les liens dans AI Search sans fournir de nouvelles données de clic\u003C/a> dans la Search Console. Vous pouvez apparaître comme source citée dans une AI Overview sans que cette impression ou ce clic apparaisse dans vos rapports.\u003C/p>\n\u003Cp>Cela crée un angle mort analytique considérable. Si votre site est cité dans 30 % des AI Overviews de votre verticale mais que vous ne voyez aucune donnée correspondante, votre perception de la performance SEO est biaisée.\u003C/p>\n\u003Cp>Pour commencer à tracer ces interactions côté serveur, vous pouvez identifier les referrers spécifiques aux clics provenant d'AI Overviews. Google utilise des paramètres UTM et des referrer paths distincts. Voici une configuration Nginx pour logger ces hits séparément :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># /etc/nginx/conf.d/ai-search-tracking.conf\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Map pour identifier les referrers AI Search de Google\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $\u003C/span>\u003Cspan style=\"color:#FFAB70\">http_referer\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $is_ai_search_referrer {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">    default\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"~*google\\.com/search.*udm=14\"\u003C/span>\u003Cspan style=\"color:#79B8FF\">  1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:#6A737D\"># AI Mode\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"~*google\\.com/search.*sourceid=ai\"\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"~*google\\.com.*ai-overview\"\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\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:#6A737D\"># Map pour identifier l'user-agent Google Extended (AI features)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">map\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $\u003C/span>\u003Cspan style=\"color:#FFAB70\">http_user_agent\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> $is_google_extended {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">    default\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"~*Google-Extended\"\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 1\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:#6A737D\"># Log format dédié avec le flag AI search\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">log_format \u003C/span>\u003Cspan style=\"color:#E1E4E8\">ai_search_log \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'$\u003C/span>\u003Cspan style=\"color:#E1E4E8\">remote_addr\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> - $\u003C/span>\u003Cspan style=\"color:#E1E4E8\">time_iso8601\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    '\"$\u003C/span>\u003Cspan style=\"color:#E1E4E8\">request_uri\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\" $\u003C/span>\u003Cspan style=\"color:#E1E4E8\">status\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    '\"$\u003C/span>\u003Cspan style=\"color:#E1E4E8\">http_referer\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\" '\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    '\"$\u003C/span>\u003Cspan style=\"color:#E1E4E8\">http_user_agent\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\" '\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'ai_ref=$\u003C/span>\u003Cspan style=\"color:#E1E4E8\">is_ai_search_referrer\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> '\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'g_ext=$\u003C/span>\u003Cspan style=\"color:#E1E4E8\">is_google_extended\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'\u003C/span>\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:#6A737D\">    # ... votre config existante ...\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Log séparé pour le trafic AI search\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    access_log \u003C/span>\u003Cspan style=\"color:#E1E4E8\">/var/log/nginx/ai_search_access.log ai_search_log\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        if=$is_ai_search_referrer;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Log séparé pour les crawls Google Extended\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    access_log \u003C/span>\u003Cspan style=\"color:#E1E4E8\">/var/log/nginx/google_extended.log ai_search_log\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        if=$is_google_extended;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ce n'est pas parfait — Google ne documente pas publiquement tous les patterns de referrer pour AI Search, et ils changent régulièrement. Mais c'est mieux que l'angle mort total. Croisez ces logs serveur avec vos données Search Console pour estimer le delta.\u003C/p>\n\u003Ch3>Les subscription labels changent la donne pour les sites paywall\u003C/h3>\n\u003Cp>L'ajout de labels « subscription » dans AI Search est un signal fort : Google indique explicitement aux utilisateurs que le contenu source est payant. Pour les éditeurs qui dépendent d'un modèle freemium/paywall, cela change l'équation.\u003C/p>\n\u003Cp>Le risque : l'utilisateur obtient la réponse via l'AI Overview et ne clique jamais sur la source payante, le label « subscription » agissant comme un repoussoir supplémentaire.\u003C/p>\n\u003Cp>L'opportunité : si Google labellise votre contenu comme « subscription », c'est une reconnaissance implicite de sa valeur en tant que source primaire. Et \u003Ca href=\"/blog/4-signals-that-now-define-visibility-in-ai-search\">les signaux qui définissent la visibilité en AI Search\u003C/a> montrent que les sources perçues comme autoritaires et originales sont davantage citées.\u003C/p>\n\u003Cp>Pour les sites avec paywall, la config \u003Ccode>structured data\u003C/code> des articles doit être irréprochable :\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:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#B392F0\"> type\u003C/span>\u003Cspan style=\"color:#E1E4E8\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"application/ld+json\"\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\">  \"@context\": \"https://schema.org\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"@type\": \"NewsArticle\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"headline\": \"Analyse exclusive du marché des semi-conducteurs Q2 2025\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"datePublished\": \"2025-05-08T09:00:00+02:00\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"dateModified\": \"2025-05-09T14:30:00+02:00\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"author\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@type\": \"Person\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"name\": \"Marie Dupont\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"url\": \"https://www.votremedia.fr/auteurs/marie-dupont\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"jobTitle\": \"Analyste senior semi-conducteurs\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"sameAs\": [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"https://www.linkedin.com/in/mariedupont-analyst\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"https://twitter.com/mdupont_semicon\"\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\">  \"publisher\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@type\": \"Organization\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"name\": \"Votre Média Tech\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"logo\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"@type\": \"ImageObject\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      \"url\": \"https://www.votremedia.fr/logo.png\"\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\">  \"isAccessibleForFree\": false,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"hasPart\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@type\": \"WebPageElement\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"isAccessibleForFree\": false,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"cssSelector\": \".article-body-premium\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \"mainEntityOfPage\": {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@type\": \"WebPage\",\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \"@id\": \"https://www.votremedia.fr/analyse-semiconducteurs-q2-2025\"\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\">&#x3C;/\u003C/span>\u003Cspan style=\"color:#85E89D\">script\u003C/span>\u003Cspan style=\"color:#E1E4E8\">>\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Le champ \u003Ccode>isAccessibleForFree: false\u003C/code> couplé au \u003Ccode>hasPart\u003C/code> avec \u003Ccode>cssSelector\u003C/code> permet à Google de comprendre précisément quelle portion du contenu est derrière le paywall. Sans cette déclaration, Google peut mal interpréter votre modèle et soit ignorer votre contenu, soit le traiter comme du cloaking si le markup ne correspond pas à la réalité visible par Googlebot.\u003C/p>\n\u003Cp>Référence : la \u003Ca href=\"https://developers.google.com/search/docs/appearance/structured-data/paywalled-content\">documentation officielle de Google sur les contenus paywall et le structured data\u003C/a> détaille les exigences techniques.\u003C/p>\n\u003Ch2>Mueller sur le « vibe coding » : signal faible, impact structurel\u003C/h2>\n\u003Cp>John Mueller a commenté le phénomène du « vibe coding » — la pratique de générer du code entier via des LLM sans le relire en détail. Sa position est mesurée mais le message est clair : Google ne pénalise pas le code généré par IA en soi, mais les conséquences techniques d'un code mal maîtrisé impactent le SEO indirectement.\u003C/p>\n\u003Cp>Le lien avec le Core Update est direct. Voici un scénario réel que nous observons de plus en plus.\u003C/p>\n\u003Ch3>Scénario : un SaaS de 8 000 pages génère son frontend avec un LLM\u003C/h3>\n\u003Cp>Un SaaS B2B a migré son marketing site de Gatsby vers Next.js en utilisant massivement Cursor + Claude pour générer les composants. Le résultat visuel était correct. Le résultat SEO, catastrophique :\u003C/p>\n\u003Cp>\u003Cstrong>Avant la migration\u003C/strong> : 8 200 pages indexées, position moyenne 12.4, 45 000 clics/mois.\u003C/p>\n\u003Cp>\u003Cstrong>3 semaines après\u003C/strong> : 3 100 pages indexées, position moyenne 28.7, 11 000 clics/mois.\u003C/p>\n\u003Cp>Les causes identifiées via un crawl Screaming Frog + analyse des logs serveur :\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Le LLM a généré du client-side rendering par défaut\u003C/strong> pour 60 % des pages. Les composants utilisaient \u003Ccode>useEffect\u003C/code> pour fetcher les données, rendant le contenu invisible au crawl initial. Le SSR était configuré dans \u003Ccode>next.config.js\u003C/code> mais le code généré court-circuitait le mécanisme.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Les balises canonical auto-générées pointaient vers des URLs avec des paramètres de session\u003C/strong>. Le template généré par l'IA incluait un \u003Ccode>useRouter\u003C/code> qui ajoutait des query params au canonical.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Les liens internes utilisaient un composant custom \u003Ccode>&#x3C;Link>\u003C/code> qui effectuait une navigation client-side sans \u003Ccode>&#x3C;a href>\u003C/code>\u003C/strong>, rendant le maillage interne invisible pour Googlebot.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>Le problème n'est pas que le code est généré par IA. Le problème est que personne n'a audité les outputs avec un regard SEO technique. C'est exactement le type de \u003Ca href=\"/blog/google-s-quality-threshold-is-quietly-killing-scaled-ai-content-via-sejournal-taylordanrw\">régression que le quality threshold de Google cible\u003C/a> — pas une pénalité manuelle, mais une dégradation technique qui fait naturellement sortir les pages de l'index.\u003C/p>\n\u003Cp>Pour détecter ce type de régression avant que Google ne la sanctionne, un monitoring continu des meta tags, du statut SSR et des canonicals est indispensable. Un outil comme Seogard détecte ces cassures dès qu'elles apparaissent en production, avant que l'impact ne se propage dans les SERPs.\u003C/p>\n\u003Cp>Commande Screaming Frog pour valider le rendu JavaScript de vos pages critiques :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Crawl en mode JavaScript rendering avec Screaming Frog CLI\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Vérifie que le contenu est bien rendu server-side\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">screaming-frog-cli\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --crawl\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"https://www.votresaas.com/features\"\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --headless\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --config\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> js-rendering-config.seospiderconfig\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --export-tabs\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"Internal:All,Response Codes:All\"\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --output-folder\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> /tmp/sf-audit/\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --max-crawl-depth\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 4\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --limit-crawl-total\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 5000\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --render-js\u003C/span>\u003Cspan style=\"color:#79B8FF\"> true\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">  --js-rendering-wait\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 8000\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># Puis comparer le HTML initial vs le HTML rendu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># pour identifier les pages où le contenu n'apparaît qu'après JS execution\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">diff\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> &#x3C;(\u003C/span>\u003Cspan style=\"color:#B392F0\">curl\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -s\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"https://www.votresaas.com/features\" \u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#B392F0\"> htmlq\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> 'h1,h2,p' \u003C/span>\u003Cspan style=\"color:#79B8FF\">--text\u003C/span>\u003Cspan style=\"color:#9ECBFF\">)\u003C/span>\u003Cspan style=\"color:#79B8FF\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">     &#x3C;(\u003C/span>\u003Cspan style=\"color:#B392F0\">node\u003C/span>\u003Cspan style=\"color:#79B8FF\"> -e\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">       const puppeteer = require('puppeteer');\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">       (async () => {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">         const browser = await puppeteer.launch({headless: 'new'});\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">         const page = await browser.newPage();\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">         await page.goto('https://www.votresaas.com/features', {waitUntil: 'networkidle0'});\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">         const text = await page.evaluate(() => {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">           return [...document.querySelectorAll('h1,h2,p')].map(el => el.textContent).join('\\n');\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">         });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">         console.log(text);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">         await browser.close();\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">       })();\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">     \")\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Si le \u003Ccode>diff\u003C/code> montre du contenu manquant dans le \u003Ccode>curl\u003C/code> (HTML statique) mais présent dans le rendu Puppeteer, vos pages ont un problème de SSR. Google peut éventuellement exécuter le JavaScript, mais le délai de rendering et le crawl budget consommé jouent contre vous, surtout lors d'un Core Update où Google réévalue massivement la qualité.\u003C/p>\n\u003Ch2>Preferred Sources : Google officialise la hiérarchie des sources\u003C/h2>\n\u003Cp>La feature Preferred Sources, mentionnée par Mueller et observable dans les résultats récents, permet à Google de prioriser certaines sources pour des types de requêtes spécifiques. Ce n'est pas un programme opt-in — c'est un signal algorithmique basé sur l'historique de fiabilité, la cohérence thématique et l'autorité perçue d'un domaine sur un topic cluster donné.\u003C/p>\n\u003Cp>Les implications techniques sont profondes. Google ne regarde plus uniquement la pertinence page-level pour une requête donnée. Il évalue si votre domaine est une « source préférée » pour une thématique entière.\u003C/p>\n\u003Ch3>Comment auditer votre statut de source sur un topic\u003C/h3>\n\u003Cp>L'approche la plus fiable consiste à analyser votre couverture thématique dans la Search Console et la comparer à celle de vos concurrents qui gagnent en visibilité.\u003C/p>\n\u003Cp>Étape 1 : exportez toutes vos requêtes sur 3 mois et clusterisez-les par entité principale (outil : Python + un modèle d'embeddings, ou plus simplement, un clustering par n-grams partagés).\u003C/p>\n\u003Cp>Étape 2 : pour chaque cluster, calculez votre « taux de couverture » — le ratio entre le nombre de requêtes pour lesquelles vous avez au moins une page en top 20 et le nombre total de requêtes dans le cluster.\u003C/p>\n\u003Cp>Étape 3 : identifiez les clusters où votre couverture est inférieure à 40 %. Ce sont vos « trous topiques » — les zones où Google ne vous considère pas comme une source préférée.\u003C/p>\n\u003Cp>Ce travail rejoint directement l'approche de \u003Ca href=\"/blog/a-blueprint-for-semantic-programmatic-seo\">SEO programmatique sémantique\u003C/a> : combler les trous topiques avec du contenu structuré qui couvre les entités manquantes dans votre maillage.\u003C/p>\n\u003Cp>L'erreur serait de publier 200 articles thin pour couvrir ces gaps. Le \u003Ca href=\"/blog/google-s-quality-threshold-is-quietly-killing-scaled-ai-content-at-ranking-via-sejournal-taylordanrw\">quality threshold de Google élimine précisément ce type d'approche\u003C/a>. Il faut moins de pages, mais plus denses, avec des données propriétaires ou un angle éditorial que vos concurrents ne couvrent pas.\u003C/p>\n\u003Ch2>Le lien entre Core Update et AI Search : convergence des signaux\u003C/h2>\n\u003Cp>La simultanéité du Core Update et de l'expansion des liens AI Search n'est pas une coïncidence. Google aligne progressivement les critères de ranking organique classique avec les critères de citation dans AI Overviews.\u003C/p>\n\u003Cp>Les sites qui gagnent dans le Core Update sont souvent les mêmes qui voient leur citation rate augmenter dans AI Search. Pourquoi ? Parce que les signaux convergent :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Source primaire vs agrégateur\u003C/strong> : AI Search cite prioritairement la source originale d'une information. Le Core Update déclasse les agrégateurs qui reformulent sans ajouter de valeur. Même logique.\u003C/li>\n\u003Cli>\u003Cstrong>Structured data cohérent\u003C/strong> : les AI Overviews s'appuient sur le knowledge graph et le structured data pour sélectionner les sources. Les sites dont le markup est cassé ou incohérent sont invisibles dans les deux canaux.\u003C/li>\n\u003Cli>\u003Cstrong>Autorité thématique\u003C/strong> : le concept de Preferred Sources dans le ranking classique et la sélection de sources dans AI Search reposent sur le même graphe d'autorité topique.\u003C/li>\n\u003C/ul>\n\u003Cp>Si vous travaillez votre \u003Ca href=\"/blog/500m-ai-searches-later-how-to-actually-improve-ai-search-visibility-citations-via-sejournal-mattgsouthern\">visibilité en AI Search\u003C/a>, vous travaillez aussi votre résilience aux Core Updates. Et inversement.\u003C/p>\n\u003Cp>L'observation de \u003Ca href=\"/blog/how-ai-models-understand-your-brand\">comment les modèles IA comprennent votre marque\u003C/a> éclaire un point souvent négligé : la représentation de votre site dans les embeddings des LLM influence à la fois votre citation dans AI Search et la perception de votre autorité par les systèmes de ranking de Google, qui intègrent de plus en plus de composants basés sur des modèles de langage.\u003C/p>\n\u003Ch2>Plan d'action post-Core Update : checklist technique\u003C/h2>\n\u003Cp>Plutôt qu'une liste générique, voici un workflow séquentiel adapté à un site de 5 000 à 50 000 pages qui vient de subir un Core Update.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 1 — Diagnostic (J+0 à J+3)\u003C/strong>\u003C/p>\n\u003Cp>Identifiez le type de pages impactées. Utilisez le script Search Console ci-dessus. Regroupez les résultats par template. Si 80 % des pertes viennent de vos pages de listing, le problème n'est pas votre blog.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 2 — Audit technique ciblé (J+3 à J+7)\u003C/strong>\u003C/p>\n\u003Cp>Crawlez uniquement les templates impactés avec Screaming Frog. Vérifiez :\u003C/p>\n\u003Cul>\n\u003Cli>Cohérence canonical (self-referencing, pas de chaînes)\u003C/li>\n\u003Cli>Présence et validité du structured data sur chaque page\u003C/li>\n\u003Cli>Ratio contenu unique vs contenu dupliqué (surtout pour les pages de catégorie e-commerce qui n'affichent que des extraits produits)\u003C/li>\n\u003Cli>Headers HTTP : \u003Ccode>Last-Modified\u003C/code> cohérent avec \u003Ccode>dateModified\u003C/code> du structured data\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Phase 3 — Correction et consolidation (J+7 à J+30)\u003C/strong>\u003C/p>\n\u003Cp>Priorisez les corrections par impact potentiel. Les pages qui étaient en position 5-15 avant l'update et qui sont tombées en 20-40 sont les plus récupérables. Les pages qui étaient en position 30+ et qui sont tombées en 50+ ne valent probablement pas l'effort — considérez leur suppression ou leur consolidation.\u003C/p>\n\u003Cp>Pour la consolidation, vérifiez que vos redirections ne créent pas de chaînes. Un classique post-Core Update : fusionner 3 pages thin en 1 page dense, mais oublier de mettre à jour les liens internes qui pointent encore vers les anciennes URLs, créant des chaînes de redirects 301 qui diluent le link equity.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 4 — Monitoring continu (J+30+)\u003C/strong>\u003C/p>\n\u003Cp>Le prochain Core Update arrivera. La question n'est pas si, mais quand. La capacité à détecter une régression technique le jour où elle apparaît — une meta title qui disparaît après un déploiement, un canonical qui se casse, un SSR qui tombe — fait la différence entre un site qui oscille d'update en update et un site qui progresse régulièrement. C'est exactement ce que Seogard automatise : un monitoring continu qui vous alerte avant que Googlebot ne constate les dégâts.\u003C/p>\n\u003Ch2>Ce qu'il faut retenir\u003C/h2>\n\u003Cp>Ce Core Update confirme la direction prise par Google depuis deux ans : les sources primaires, thématiquement cohérentes et techniquement irréprochables gagnent du terrain. Les agrégateurs et les sites qui comptent sur leur autorité de domaine pour ranker du contenu superficiel reculent. En parallèle, \u003Ca href=\"/blog/google-updates-links-within-ai-overviews-ai-mode\">l'expansion des liens dans AI Search\u003C/a> crée un nouveau canal de visibilité — mais aussi un nouvel angle mort analytique que vous devez combler côté serveur. L'alignement de votre stratégie SEO classique avec votre visibilité en AI Search n'est plus optionnel : c'est le même jeu, joué sur deux tableaux.\u003C/p>\n\u003Cpre>\u003Ccode>\u003C/code>\u003C/pre>",null,12,[18,19,20,21,22],"google","core update","AI search","winners losers","monitoring SEO","Core Update mai 2025 : analyse technique des gagnants et perdants","Sun May 10 2026 06:02:51 GMT+0000 (Coordinated Universal Time)",[26,40,56],{"_id":27,"slug":28,"__v":6,"author":7,"canonical":29,"category":10,"createdAt":30,"date":31,"description":32,"image":15,"imageAlt":15,"readingTime":16,"tags":33,"title":38,"updatedAt":39},"6a041412aa6b273b0c40f181","how-to-build-local-pages-that-win-in-ai-powered-search-via-sejournal-lorenbaker","https://seogard.io/blog/how-to-build-local-pages-that-win-in-ai-powered-search-via-sejournal-lorenbaker","2026-05-13T06:02:58.743Z","2026-05-13","Guide technique pour construire des pages locales qui performent dans les AI Overviews et AI Mode. Schema, SSR, contenu structuré.",[34,20,35,36,37],"local SEO","pages locales","schema markup","SSR","Pages locales pour l'AI Search : architecture technique","Wed May 13 2026 06:02:58 GMT+0000 (Coordinated Universal Time)",{"_id":41,"slug":42,"__v":6,"author":7,"canonical":43,"category":10,"createdAt":44,"date":45,"description":46,"image":15,"imageAlt":15,"readingTime":47,"tags":48,"title":54,"updatedAt":55},"6a02c291aa6b273b0c2a74f9","the-tech-seo-audit-for-the-ai-search-era-how-to-maximize-your-ai-visibility-via-sejournal-jetoctopus","https://seogard.io/blog/the-tech-seo-audit-for-the-ai-search-era-how-to-maximize-your-ai-visibility-via-sejournal-jetoctopus","2026-05-12T06:02:57.339Z","2026-05-12","Comment adapter votre audit technique SEO aux exigences des AI Overviews, du crawl par les LLMs et du grounding. Méthodes, code et scénarios concrets.",14,[49,50,51,52,53],"tech seo audit","ai search","ai visibility","crawl budget","structured data","Audit SEO technique pour l'ère AI Search : guide avancé","Tue May 12 2026 06:02:57 GMT+0000 (Coordinated Universal Time)",{"_id":57,"slug":58,"__v":6,"author":7,"canonical":59,"category":10,"createdAt":60,"date":45,"description":61,"image":15,"imageAlt":15,"readingTime":16,"tags":62,"title":67,"updatedAt":68},"6a02fac0aa6b273b0c58d096","the-consensus-gap-via-sejournal-kevin-indig","https://seogard.io/blog/the-consensus-gap-via-sejournal-kevin-indig","2026-05-12T10:02:40.519Z","Une marque peut dominer dans un dashboard AI agrégé et être absente de deux moteurs sur trois. Analyse technique du Consensus Gap et méthodes pour le détecter.",[63,20,64,65,66],"consensus gap","LLM visibility","GEO","multi-engine","The Consensus Gap : votre marque visible sur un LLM, invisible sur deux autres","Tue May 12 2026 10:02:40 GMT+0000 (Coordinated Universal Time)"]