Un site e-commerce de 22 000 pages, parfaitement indexé dans Google Search, qui disparaît des AI Overviews du jour au lendemain. Le crawl organique n'a pas bougé, les positions classiques sont stables, mais le trafic fond de 18 % en six semaines. Le problème n'est pas dans les SERPs traditionnelles — il est dans la couche d'extraction que les modèles de langage utilisent pour construire leurs réponses. L'audit SEO technique tel qu'on le pratiquait depuis dix ans ne couvre plus ce périmètre.
L'article récemment publié par Search Engine Journal en collaboration avec JetOctopus pose les bases d'un audit adapté à l'ère de l'AI Search. Mais le cadre proposé mérite d'être poussé beaucoup plus loin — avec du code, des scénarios de production réels, et une méthodologie exploitable dès demain.
Le shift fondamental : de l'indexation à la citabilité
L'audit technique classique vérifie que vos pages sont crawlables, indexables et rendues correctement. Ces trois piliers restent nécessaires, mais ils ne sont plus suffisants. Les systèmes d'AI Search — Google AI Overviews, Bing Copilot, Perplexity — ajoutent une quatrième dimension : la citabilité.
La citabilité, c'est la capacité d'une page à être sélectionnée comme source fiable par un LLM lors du processus de grounding. Le grounding est le mécanisme par lequel un modèle ancre sa réponse dans des documents vérifiables plutôt que de générer du texte à partir de ses seuls paramètres.
Ce que le grounding exige de vos pages
Pour qu'une page soit "grounded", elle doit répondre à des critères que l'audit classique ignore :
- Extraction propre du contenu principal : le LLM doit pouvoir isoler le contenu informatif du chrome (navigation, sidebar, footer). Un ratio signal/bruit trop faible exclut la page.
- Structure sémantique explicite : les heading levels, les listes, les tableaux ne sont pas décoratifs — ils servent de points d'ancrage pour le chunking du texte par le système de retrieval.
- Fraîcheur vérifiable : les dates de publication et de mise à jour doivent être présentes dans le HTML et dans les données structurées, pas uniquement dans le texte visible.
- Autorité thématique : le maillage interne et les entités mentionnées permettent au système de positionner la page dans un graph de connaissances thématique.
Ce n'est pas de la spéculation. Bing a explicitement décrit comment le grounding diffère de l'indexation traditionnelle, et Google a progressivement élargi les liens dans les AI Overviews — signe que le mécanisme de sélection des sources se raffine.
Auditer le crawl des AI bots : un angle mort critique
La première couche de votre audit doit désormais vérifier qui crawle votre site, pas seulement comment Googlebot le voit. Les AI bots — GPTBot (OpenAI), ClaudeBot (Anthropic), Google-Extended, Bytespider (ByteDance), PerplexityBot — ont des comportements de crawl différents et des user-agents distincts.
Identifier les AI bots dans vos logs
Avant de décider quoi que ce soit, mesurez. Voici une commande pour extraire et compter les requêtes par AI bot depuis vos access logs :
#!/bin/bash
# Extraction des AI bots depuis les access logs Nginx
# Adapter le chemin et le format de log selon votre config
LOG_FILE="/var/log/nginx/access.log"
echo "=== AI Bot Crawl Report ==="
echo ""
for BOT in "GPTBot" "ClaudeBot" "Google-Extended" "PerplexityBot" "Bytespider" "CCBot" "anthropic-ai" "Applebot-Extended"; do
COUNT=$(grep -c "$BOT" "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$COUNT" -gt 0 ]; then
UNIQUE_URLS=$(grep "$BOT" "$LOG_FILE" | awk '{print $7}' | sort -u | wc -l)
STATUS_5XX=$(grep "$BOT" "$LOG_FILE" | awk '{print $9}' | grep -c "^5" || echo 0)
echo "$BOT: $COUNT requêtes | $UNIQUE_URLS URLs uniques | $STATUS_5XX erreurs 5xx"
fi
done
echo ""
echo "=== Pages les plus crawlées par les AI bots ==="
grep -E "(GPTBot|ClaudeBot|Google-Extended|PerplexityBot)" "$LOG_FILE" \
| awk '{print $7}' \
| sort | uniq -c | sort -rn | head -20
Ce script vous donne une vision immédiate. Dans beaucoup de cas, vous allez découvrir que certains hébergeurs WordPress managés bloquent ces bots sans que vous le sachiez.
La politique robots.txt pour les AI bots
Le choix de bloquer ou autoriser les AI bots est stratégique, pas technique. Mais la mise en œuvre, elle, est technique et source d'erreurs. Voici un pattern de robots.txt qui donne un contrôle granulaire :
# robots.txt — Politique AI bots
# Autoriser le crawl Google (y compris pour AI Overviews)
User-agent: Googlebot
Allow: /
# Google-Extended contrôle l'usage pour l'entraînement des modèles
# Le bloquer N'empêche PAS l'apparition dans AI Overviews
User-agent: Google-Extended
Disallow: /
# Autoriser GPTBot pour être cité dans ChatGPT Search
User-agent: GPTBot
Allow: /
Disallow: /account/
Disallow: /admin/
Disallow: /checkout/
# Autoriser PerplexityBot (source de trafic référent mesurable)
User-agent: PerplexityBot
Allow: /
Crawl-delay: 2
# Bloquer les scrapers d'entraînement sans contrepartie
User-agent: CCBot
Disallow: /
User-agent: Bytespider
Disallow: /
Point crucial : Google-Extended contrôle uniquement l'utilisation de vos contenus pour l'entraînement des modèles Gemini. Le bloquer ne vous exclut pas des AI Overviews — celles-ci s'appuient sur Googlebot. Google a d'ailleurs commencé à tester un nouveau standard d'autorisation pour les bots, ce qui confirme que la granularité va s'affiner.
Le rendering JavaScript : le goulot d'étranglement pour l'AI Search
Les AI bots ne rendent pas tous le JavaScript. GPTBot et PerplexityBot, en particulier, se comportent davantage comme des crawlers statiques. Si votre contenu dépend d'un hydratation côté client, il est potentiellement invisible pour la moitié des systèmes d'AI Search.
Ce problème n'est pas nouveau — c'est le même que le SEO JavaScript classique, mais amplifié. Google peut se permettre un rendering headless à grande échelle. Un bot comme ClaudeBot, non.
Diagnostic : votre contenu est-il accessible sans JS ?
// Script Node.js pour comparer le DOM avec et sans JS rendering
// Utilise puppeteer pour le rendu JS, et fetch pour le HTML brut
import puppeteer from 'puppeteer';
async function compareRendering(url) {
// 1. Récupérer le HTML brut (ce que voient GPTBot, PerplexityBot)
const rawResponse = await fetch(url, {
headers: { 'User-Agent': 'Mozilla/5.0 (compatible; GPTBot/1.0)' }
});
const rawHTML = await rawResponse.text();
// 2. Récupérer le DOM rendu (ce que voit Googlebot avec WRS)
const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });
const renderedHTML = await page.content();
// 3. Extraire le contenu textuel du <main> ou du premier article
const extractMainText = (html) => {
const mainMatch = html.match(/<main[^>]*>([\s\S]*?)<\/main>/i)
|| html.match(/<article[^>]*>([\s\S]*?)<\/article>/i);
if (!mainMatch) return '';
return mainMatch[1].replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
};
const rawText = extractMainText(rawHTML);
const renderedText = extractMainText(renderedHTML);
// 4. Calculer le ratio de contenu disponible sans JS
const ratio = rawText.length > 0
? (rawText.length / renderedText.length * 100).toFixed(1)
: 0;
console.log(`URL: ${url}`);
console.log(`Texte brut (sans JS): ${rawText.length} caractères`);
console.log(`Texte rendu (avec JS): ${renderedText.length} caractères`);
console.log(`Ratio de contenu accessible sans JS: ${ratio}%`);
if (ratio < 60) {
console.log('⚠ ALERTE: Plus de 40% du contenu nécessite JavaScript');
console.log(' → Ce contenu est probablement invisible pour GPTBot et PerplexityBot');
}
// 5. Vérifier les meta tags critiques
const metaCheck = (html, name) => {
const regex = new RegExp(`<meta[^>]*(?:name|property)=["']${name}["'][^>]*content=["']([^"']*)["']`, 'i');
return regex.test(html);
};
const criticalMeta = ['description', 'og:title', 'og:description', 'article:published_time'];
for (const meta of criticalMeta) {
const inRaw = metaCheck(rawHTML, meta);
const inRendered = metaCheck(renderedHTML, meta);
if (!inRaw && inRendered) {
console.log(`⚠ Meta "${meta}" injectée côté client uniquement — invisible pour les AI bots`);
}
}
await browser.close();
}
// Lancer sur un échantillon de pages
const urls = [
'https://shop.example.fr/categorie/chaussures-running',
'https://shop.example.fr/produit/nike-pegasus-41',
'https://shop.example.fr/guide/choisir-chaussure-running',
];
for (const url of urls) {
await compareRendering(url);
console.log('---');
}
Ce script vous donne un diagnostic clair. Les leçons JavaScript SEO tirées des grands e-commerces s'appliquent directement ici, mais avec un enjeu supplémentaire : les AI bots n'attendent pas une seconde vague de rendering.
Scénario réel : migration SSR et impact AI visibility
Un site média français (18 000 articles, 2,3M de sessions/mois) fonctionnait en React SPA avec un rendu côté client pour le corps des articles. Googlebot rendait correctement via le Web Rendering Service, et les positions classiques étaient solides.
En janvier 2026, l'équipe constate que leurs articles n'apparaissent quasiment jamais dans les AI Overviews, malgré une autorité thématique forte sur leur verticale (tech B2B). L'analyse des logs révèle :
- GPTBot crawlait 4 200 pages/semaine mais ne récupérait que le shell HTML — titres et navigation, sans corps d'article
- PerplexityBot avait un comportement similaire
- Google-Extended n'était pas bloqué, mais le contenu textuel dans le HTML initial représentait 12 % du contenu rendu
La migration vers Next.js App Router en mode SSR (pas SSG — le contenu change trop souvent) prend 11 semaines. Les résultats après 8 semaines de stabilisation :
- Ratio de contenu sans JS : de 12 % à 94 %
- Apparitions dans AI Overviews : de ~15/semaine à ~180/semaine (mesuré via le rapport AI dans Search Console)
- Trafic référent depuis les AI search (Perplexity, ChatGPT) : +340 %
- Positions classiques : inchangées (le contenu était déjà indexé correctement par Googlebot)
Ce cas illustre un point essentiel : l'audit classique ne détecte pas le problème parce que Googlebot ne le subit pas. Seule l'analyse différenciée par user-agent le révèle.
Données structurées : de Schema.org au grounding pipeline
Les données structurées jouent un rôle différent dans le contexte AI Search. Pour le SEO classique, elles déclenchent des rich results. Pour les LLMs, elles servent de métadonnées machine-readable qui facilitent le chunking, l'attribution et la vérification factuelle.
Le minimum structuré pour la citabilité AI
<head>
<!-- Métadonnées temporelles — critiques pour le grounding -->
<meta property="article:published_time" content="2026-05-10T08:00:00+02:00" />
<meta property="article:modified_time" content="2026-05-11T14:30:00+02:00" />
<!-- Auteur explicite — les LLMs pondèrent l'autorité -->
<meta name="author" content="Marie Dupont" />
<link rel="author" href="https://shop.example.fr/equipe/marie-dupont" />
</head>
<body>
<article>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Comment configurer le SSR Next.js pour un e-commerce de 15K pages",
"description": "Guide technique pour migrer un e-commerce React SPA vers Next.js SSR sans perte de positions.",
"datePublished": "2026-05-10T08:00:00+02:00",
"dateModified": "2026-05-11T14:30:00+02:00",
"author": {
"@type": "Person",
"name": "Marie Dupont",
"url": "https://shop.example.fr/equipe/marie-dupont",
"jobTitle": "Lead SEO",
"worksFor": {
"@type": "Organization",
"name": "ShopExample",
"url": "https://shop.example.fr"
}
},
"publisher": {
"@type": "Organization",
"name": "ShopExample",
"url": "https://shop.example.fr",
"logo": {
"@type": "ImageObject",
"url": "https://shop.example.fr/logo.png"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://shop.example.fr/guide/ssr-nextjs-ecommerce"
},
"about": [
{ "@type": "Thing", "name": "Server-Side Rendering", "sameAs": "https://en.wikipedia.org/wiki/Server-side_scripting" },
{ "@type": "Thing", "name": "Next.js", "sameAs": "https://nextjs.org" },
{ "@type": "Thing", "name": "E-commerce SEO" }
],
"speakable": {
"@type": "SpeakableSpecification",
"cssSelector": ["article h2", "article > p:first-of-type", ".key-takeaway"]
}
}
</script>
<h1>Comment configurer le SSR Next.js pour un e-commerce de 15K pages</h1>
<!-- Corps de l'article directement dans le HTML initial -->
</article>
</body>
Quelques choix délibérés dans ce markup :
speakable : cette propriété Schema.org indique quelles parties du contenu sont les plus pertinentes pour une extraction vocale ou textuelle. Google la supporte officiellement pour Google Assistant et elle est directement utile pour le chunking AI. Peu de sites l'implémentent.
about avec sameAs : lier vos entités à des références canoniques (Wikipedia, sites officiels) aide le modèle à désambiguïser. Si vous écrivez sur "Mercury", le sameAs vers la page Wikipedia de la planète vs. celle du logiciel change complètement le contexte de grounding.
TechArticle vs Article : le type spécialisé donne un signal de profondeur technique. Google n'en a jamais confirmé l'impact direct sur le ranking, mais pour un système de retrieval qui filtre par pertinence thématique, la granularité du type aide.
Audit de la structure sémantique : au-delà des headings
Les LLMs travaillent par chunks. La façon dont votre contenu est structuré détermine la qualité des passages extraits. Un article long sans structure claire produit des chunks bruités — et un chunk bruité ne sera pas sélectionné comme source.
Les patterns HTML qui favorisent l'extraction
Sections thématiques explicites : utilisez des <section> avec des aria-labelledby liés aux headings. Cela crée des blocs sémantiques autonomes.
<section aria-labelledby="config-nginx">
<h2 id="config-nginx">Configuration Nginx pour le SSR</h2>
<p>La configuration du reverse proxy est le point de friction principal...</p>
<h3 id="cache-strategy">Stratégie de cache</h3>
<p>Un TTL de 60 secondes sur les pages catégorie représente le meilleur
compromis entre fraîcheur et performance pour un catalogue de 15K produits...</p>
<div class="key-takeaway" role="note">
<strong>Point clé :</strong> Le cache SSR côté Nginx réduit le TTFB de 1,2s
à 180ms en moyenne, sans impact sur la fraîcheur de l'index produit.
</div>
</section>
Tableaux de données : les LLMs extraient les tableaux beaucoup mieux que les paragraphes de comparaison. Si vous comparez des options, un <table> avec des <th> explicites sera extrait proprement.
Listes de définitions : le <dl> est sous-utilisé. Pour des glossaires, des FAQ techniques ou des spécifications, il donne un markup beaucoup plus propre que des <div> custom.
Ce que les outils classiques ne vérifient pas
Screaming Frog vérifie la hiérarchie des headings, les meta tags manquants et les problèmes de rendering. Chrome DevTools Lighthouse mesure les Core Web Vitals. Mais aucun de ces outils ne vous dit si votre contenu est extractible par un LLM.
Voici ce que vous devez ajouter à votre checklist d'audit :
- Ratio contenu/chrome : le texte dans
<main>ou<article>représente quel pourcentage du DOM total ? Sous 40 %, votre signal est noyé. - Profondeur de heading : est-ce que chaque section H2 contient au moins 150 mots de contenu propre ? Un H2 suivi immédiatement d'un H3 sans texte intermédiaire crée un chunk vide.
- Présence de "claim statements" : des phrases assertives, factuellement vérifiables, qui peuvent servir de passage extractible. Les LLMs cherchent des affirmations à grounder, pas des formulations vagues.
- Maillage interne contextuel : les liens internes dans le corps du texte (pas la navigation) servent de signal de graph thématique. La pipeline AI Search en 10 étapes décrit comment le contenu est filtré à chaque niveau — le maillage intervient dès l'étape d'évaluation de l'autorité topicale.
Monitoring continu : l'audit n'est pas un one-shot
Le piège classique : vous faites un audit technique complet, vous implémentez les correctifs, et vous passez à autre chose. Trois mois plus tard, une mise à jour du CMS réintroduit un rendering côté client sur vos pages produit, ou un développeur ajoute un noindex sur un template sans le vouloir.
Dans le contexte AI Search, les régressions sont encore plus silencieuses. Vous ne verrez pas de chute de positions dans Search Console — les données de clic AI y sont encore incomplètes. Vous verrez simplement un trafic qui s'érode sans explication visible.
Les signaux à monitorer en continu
- Changements de rendering : un diff automatisé entre le HTML initial et le DOM rendu, déclenché à chaque déploiement. Si le ratio de contenu sans JS chute sous votre seuil, alerte immédiate.
- Disparition de données structurées : un template modifié peut casser le JSON-LD sans que personne ne s'en aperçoive. Un outil de monitoring comme Seogard détecte automatiquement ce type de régression sur l'ensemble de vos pages.
- Comportement des AI bots : monitoring des logs pour détecter un changement de fréquence de crawl, une explosion d'erreurs 5xx spécifiques à certains user-agents, ou l'apparition de nouveaux bots.
- Freshness des timestamps : les pages avec un
dateModifiedde plus de 6 mois sont progressivement déprioritisées par les systèmes de grounding, qui privilégient les sources récentes.
Le concept de "votre site comme source, pas comme mégaphone" prend tout son sens ici : si votre contenu n'est pas structurellement prêt à être cité, aucune optimisation de contenu ne compensera.
La checklist d'audit AI-ready : 15 points techniques
Pour synthétiser cette approche en un workflow actionable, voici les points de contrôle à intégrer à votre audit technique existant. Ce n'est pas un remplacement — c'est une extension.
Crawl & Access Layer
- Logs serveur analysés par AI bot user-agent (pas uniquement Googlebot)
- Politique
robots.txtexplicite pour chaque AI bot majeur - Temps de réponse serveur < 500ms pour les AI bots (ils ont des timeouts courts)
- Pas de Cloudflare Bot Fight Mode ou équivalent qui bloque les AI crawlers légitimes
Rendering Layer
- Ratio de contenu accessible sans JavaScript > 80 % pour toutes les pages de contenu
- Meta tags critiques (title, description, canonical, OG, dates) présentes dans le HTML initial
- Aucune meta
noindexinjectée côté client qui ne serait pas dans la réponse serveur initiale
Structure & Extraction Layer
- Hiérarchie de headings cohérente avec au moins 150 mots par section H2
- Contenu principal encapsulé dans
<main>ou<article> - Données structurées JSON-LD avec
datePublished,dateModified,authoret entitésabout speakableimplémenté sur les contenus informationnels
Authority & Freshness Layer
- Liens internes contextuels vers les pages thématiquement proches (minimum 3 par article long)
dateModifiedmis à jour uniquement lors de modifications substantielles (pas à chaque rebuild)- Pages auteur avec markup
Personet liens vers les profils externes vérifiables
Monitoring Layer
- Alertes automatiques sur les régressions de rendering, de données structurées et de réponse aux AI bots
Chaque point devrait être vérifié non pas une fois, mais à chaque sprint de développement. L'audit ponctuel est mort — les régressions que personne ne cherche sont celles qui coûtent le plus cher.
Les limites de cette approche
Aucune de ces optimisations techniques ne garantit une apparition dans les AI Overviews. Google n'a publié aucune documentation exhaustive sur les critères de sélection des sources pour les AI-generated answers. Ce qu'on sait vient de l'ingénierie inverse, des déclarations fragmentaires des équipes Bing et Google, et de l'observation empirique.
Certains contenus ne seront jamais cités, quelle que soit leur qualité technique — parce que le LLM a suffisamment de connaissances paramétriques sur le sujet, ou parce que la requête ne déclenche pas de grounding externe. Les 500 millions de recherches AI analysées montrent que les citations sont concentrées sur un sous-ensemble de requêtes — les requêtes factuelles, techniques et comparatives.
Votre audit technique est une condition nécessaire, pas suffisante. Mais sans cette fondation, même le meilleur contenu restera invisible pour les systèmes qui construisent les réponses AI. L'ère du "publier et espérer" est terminée — la visibilité AI se construit, se mesure, et se défend en continu. Un monitoring automatisé des régressions techniques, comme celui que propose Seogard, transforme cette défense en processus systématique plutôt qu'en audit ponctuel qu'on oublie dans un tiroir.