[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f0sYCCZ94b-qoi-4Ep2x-WQ6R0RHxsNYb4DZX1Zuq2ok":3,"$fB9f6k99bj1vopV9ImKgxJs7P6SbN3QDCEmTx29_3fwk":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},"6a0b5465aa6b273b0c3ca82c","the-5-layer-framework-for-measuring-geo-performance",0,"Equipe Seogard","La plupart des équipes SEO qui investissent dans le GEO (Generative Engine Optimization) mesurent aujourd'hui une seule chose : la présence ou l'absence de leur marque dans les réponses AI. C'est comme mesurer la performance d'un e-commerce en comptant le nombre de fois où la vitrine est allumée. Le vrai problème n'est pas la visibilité — c'est le chemin entre une mention dans une réponse ChatGPT et une conversion attribuable dans votre CRM.\n\n## Pourquoi les dashboards d'AI visibility créent une illusion de mesure\n\nLes outils qui trackent la \"visibilité AI\" — apparition dans les AI Overviews de Google, citations dans ChatGPT, mentions dans Perplexity — répondent à une question binaire : êtes-vous mentionné, oui ou non ? C'est une couche nécessaire mais radicalement insuffisante.\n\nLe problème structurel est triple.\n\n**Absence de données de clic.** Google ne fournit toujours pas de données de clic spécifiques aux AI Overviews dans Search Console. Le rapport de performance agrège les impressions et clics sans distinguer un clic classique d'un clic provenant d'une réponse générée. Bing a commencé à exposer certaines métriques via le [concept de \"grounding\"](/blog/bing-reveals-what-grounding-means-for-ai-search-visibility-via-sejournal-mattgsouthern), mais la granularité reste faible.\n\n**Fragmentation des moteurs génératifs.** Votre contenu peut être cité par ChatGPT via Bing, par Perplexity via son propre index, par Google AI Overviews, par Gemini dans Google Workspace. Chaque surface a ses propres règles de citation, son propre taux de clic, son propre profil d'utilisateur. Agréger tout ça dans un score unique de \"AI visibility\" revient à additionner des impressions TV et des clics display.\n\n**Confusion entre citation et influence.** Une mention de votre marque dans une réponse AI n'implique pas que l'utilisateur a cliqué, ni qu'il a retenu votre marque, ni qu'il a converti. La corrélation entre \"être cité\" et \"générer du revenu\" est non prouvée dans la majorité des cas.\n\nC'est exactement pourquoi un framework multi-couches est indispensable : chaque couche répond à une question différente, avec des données différentes, et un niveau de confiance différent.\n\n## Couche 1 : AI Visibility Index — mesurer la présence brute\n\nLa première couche est la plus simple et la plus répandue : détecter si votre contenu ou votre marque apparaît dans les réponses génératives. C'est le socle sans lequel rien d'autre ne peut être mesuré.\n\n### Ce qu'il faut tracker concrètement\n\nPas juste \"est-ce qu'on apparaît\", mais avec quelle fréquence, sur quels types de requêtes, et avec quel positionnement dans la réponse (source primaire citée vs mention secondaire vs absence).\n\nVoici un script Node.js qui interroge périodiquement un ensemble de prompts sur l'API Perplexity et stocke les résultats pour analyse temporelle :\n\n```typescript\nimport Anthropic from \"@anthropic-ai/sdk\";\n\ninterface VisibilityCheck {\n  prompt: string;\n  engine: string;\n  brandMentioned: boolean;\n  position: \"primary_source\" | \"secondary_mention\" | \"absent\";\n  citationUrl: string | null;\n  checkedAt: string;\n}\n\nasync function checkPerplexityVisibility(\n  prompts: string[],\n  brand: string,\n  apiKey: string\n): Promise\u003CVisibilityCheck[]> {\n  const results: VisibilityCheck[] = [];\n\n  for (const prompt of prompts) {\n    const response = await fetch(\"https://api.perplexity.ai/chat/completions\", {\n      method: \"POST\",\n      headers: {\n        Authorization: `Bearer ${apiKey}`,\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify({\n        model: \"llama-3.1-sonar-large-128k-online\",\n        messages: [{ role: \"user\", content: prompt }],\n      }),\n    });\n\n    const data = await response.json();\n    const answer = data.choices?.[0]?.message?.content || \"\";\n    const citations: string[] = data.citations || [];\n\n    const brandRegex = new RegExp(brand, \"gi\");\n    const mentioned = brandRegex.test(answer);\n    const citationUrl = citations.find((c: string) =>\n      c.toLowerCase().includes(brand.toLowerCase())\n    ) || null;\n\n    results.push({\n      prompt,\n      engine: \"perplexity\",\n      brandMentioned: mentioned,\n      position: citationUrl\n        ? \"primary_source\"\n        : mentioned\n        ? \"secondary_mention\"\n        : \"absent\",\n      citationUrl,\n      checkedAt: new Date().toISOString(),\n    });\n  }\n\n  return results;\n}\n\n// Usage avec un set de prompts métier\nconst prompts = [\n  \"Quel est le meilleur outil de monitoring SEO technique ?\",\n  \"Comment détecter une régression de meta descriptions à grande échelle ?\",\n  \"Comparatif des outils de détection de soft 404\",\n];\n\ncheckPerplexityVisibility(prompts, \"seogard\", process.env.PERPLEXITY_API_KEY!)\n  .then((results) => console.log(JSON.stringify(results, null, 2)));\n```\n\nCe type de monitoring doit tourner de manière régulière (quotidienne ou hebdomadaire) pour capter les variations temporelles. Les réponses des LLM ne sont pas déterministes : une même requête peut citer votre marque un jour et l'omettre le lendemain.\n\n### Métriques de cette couche\n\n- **AI Mention Rate** : pourcentage de prompts trackés où la marque est mentionnée\n- **Primary Source Rate** : pourcentage de mentions avec lien direct en citation\n- **Volatilité** : écart-type du mention rate sur une fenêtre de 30 jours\n\nCes métriques sont détaillées dans [les 8 KPIs GEO à suivre en 2026](/blog/8-geo-metrics-to-track-in-2026). La couche 1 correspond aux métriques de \"présence\" — nécessaires mais pas suffisantes.\n\n## Couche 2 : Content Eligibility Score — qualifier ce qui peut être cité\n\nLa visibilité AI ne tombe pas du ciel. Elle dépend d'un ensemble de facteurs techniques et sémantiques qui déterminent si votre contenu est \"éligible\" à la citation par un moteur génératif. Cette couche mesure votre degré de préparation.\n\n### Les signaux d'éligibilité technique\n\nGoogle a publié un [guide officiel sur l'optimisation pour les fonctionnalités d'IA générative](https://developers.google.com/search/docs/appearance/ai-overviews) qui confirme que les mêmes fondamentaux techniques (indexabilité, données structurées, contenu de qualité) restent le socle. Mais le GEO ajoute des exigences spécifiques.\n\nLe \"grounding\" — le processus par lequel un LLM ancre sa réponse dans une source vérifiable — favorise les contenus qui présentent certaines caractéristiques structurelles :\n\n- **Réponses directes et factuelles** dans les premiers paragraphes (pattern \"inverted pyramid\")\n- **Données structurées** exploitables (Schema.org Article, FAQPage malgré la [fin des rich results FAQ](/blog/google-to-no-longer-support-faq-rich-results), HowTo)\n- **Autorité topicale** vérifiable (auteurs identifiés, citations vers des sources primaires)\n- **Fraîcheur du contenu** signalée par datePublished/dateModified\n\nVoici un audit automatisé qui vérifie l'éligibilité GEO d'une page :\n\n```python\nimport requests\nfrom bs4 import BeautifulSoup\nimport json\nfrom datetime import datetime, timedelta\n\ndef audit_geo_eligibility(url: str) -> dict:\n    \"\"\"Audite l'éligibilité GEO d'une page sur les critères techniques clés.\"\"\"\n    \n    response = requests.get(url, headers={\n        \"User-Agent\": \"Mozilla/5.0 (compatible; GEOAuditBot/1.0)\"\n    })\n    soup = BeautifulSoup(response.text, \"html.parser\")\n    \n    score = 0\n    findings = []\n    \n    # 1. Vérifier la présence de Schema.org JSON-LD\n    ld_scripts = soup.find_all(\"script\", type=\"application/ld+json\")\n    schemas = []\n    for script in ld_scripts:\n        try:\n            data = json.loads(script.string)\n            schemas.append(data)\n        except json.JSONDecodeError:\n            findings.append(\"WARN: JSON-LD invalide détecté\")\n    \n    has_article_schema = any(\n        d.get(\"@type\") in [\"Article\", \"NewsArticle\", \"TechArticle\"]\n        for d in schemas\n    )\n    if has_article_schema:\n        score += 20\n    else:\n        findings.append(\"FAIL: Pas de schema Article/NewsArticle\")\n    \n    # 2. Vérifier dateModified \u003C 90 jours\n    for schema in schemas:\n        date_mod = schema.get(\"dateModified\")\n        if date_mod:\n            try:\n                mod_date = datetime.fromisoformat(date_mod.replace(\"Z\", \"+00:00\"))\n                if (datetime.now(mod_date.tzinfo) - mod_date) \u003C timedelta(days=90):\n                    score += 15\n                else:\n                    findings.append(f\"WARN: dateModified > 90j ({date_mod})\")\n            except ValueError:\n                findings.append(f\"WARN: dateModified non parseable ({date_mod})\")\n    \n    # 3. Réponse directe dans les 150 premiers mots\n    main_content = soup.find(\"main\") or soup.find(\"article\") or soup.find(\"body\")\n    if main_content:\n        first_paras = main_content.find_all(\"p\")[:3]\n        first_text = \" \".join(p.get_text() for p in first_paras)\n        word_count = len(first_text.split())\n        if word_count >= 40:\n            score += 15\n            # Vérifier la présence de faits/chiffres dans les premiers paragraphes\n            import re\n            has_numbers = bool(re.search(r'\\d+[%$€]|\\d+\\s*(pages?|URLs?|requêtes?)', first_text))\n            if has_numbers:\n                score += 10\n                findings.append(\"OK: Données factuelles dans l'intro\")\n        else:\n            findings.append(\"WARN: Intro trop courte pour le grounding\")\n    \n    # 4. Vérifier les headers structurés (H2/H3)\n    h2_count = len(soup.find_all(\"h2\"))\n    h3_count = len(soup.find_all(\"h3\"))\n    if h2_count >= 3:\n        score += 15\n    if h3_count >= 2:\n        score += 5\n    \n    # 5. Auteur identifié\n    author_schema = any(d.get(\"author\") for d in schemas)\n    author_tag = soup.find(attrs={\"rel\": \"author\"}) or soup.find(class_=lambda c: c and \"author\" in c.lower() if c else False)\n    if author_schema or author_tag:\n        score += 10\n        findings.append(\"OK: Auteur identifié\")\n    else:\n        findings.append(\"FAIL: Pas d'auteur identifiable\")\n    \n    # 6. Canonical et indexabilité\n    canonical = soup.find(\"link\", rel=\"canonical\")\n    robots_meta = soup.find(\"meta\", attrs={\"name\": \"robots\"})\n    if canonical and robots_meta:\n        robots_content = robots_meta.get(\"content\", \"\")\n        if \"noindex\" in robots_content:\n            score -= 50\n            findings.append(\"CRITICAL: Page en noindex\")\n    \n    return {\n        \"url\": url,\n        \"geo_eligibility_score\": min(score, 100),\n        \"findings\": findings,\n        \"schema_types\": [d.get(\"@type\") for d in schemas],\n    }\n```\n\n### Le lien entre éligibilité et visibilité\n\nL'intérêt de cette couche est de mesurer l'écart entre votre potentiel d'éligibilité et votre visibilité réelle (couche 1). Un score d'éligibilité élevé avec une visibilité basse pointe vers un problème d'autorité ou de couverture topicale. Une visibilité haute avec une éligibilité basse signale que vous bénéficiez probablement de la notoriété de marque — situation fragile que n'importe quel concurrent mieux structuré peut renverser.\n\nCe type d'audit technique rejoint les recommandations du [guide d'audit tech SEO pour l'ère AI](/blog/the-tech-seo-audit-for-the-ai-search-era-how-to-maximize-your-ai-visibility-via-sejournal-jetoctopus), mais avec un focus spécifique sur les signaux de grounding.\n\n## Couche 3 : Traffic Attribution — tracer le chemin du clic AI\n\nC'est la couche la plus douloureuse. Les moteurs génératifs cassent le modèle d'attribution classique basé sur le referrer HTTP.\n\n### Le problème technique\n\nQuand un utilisateur clique sur un lien dans une réponse de ChatGPT, le referrer est généralement `https://chatgpt.com`. Quand il clique dans un AI Overview de Google, le referrer reste `https://www.google.com` — indistinguable d'un clic organique classique. Perplexity envoie son propre referrer, mais GA4 ne le catégorise pas automatiquement comme un canal dédié.\n\nGoogle a commencé à exposer le trafic provenant des assistants AI dans GA4 — un sujet couvert dans [l'analyse du tracking AI assistant dans GA4](/blog/ga4-tracks-ai-assistant-traffic-faq-results-gone-seo-pulse-via-sejournal-mattgsouthern). Mais la couverture reste partielle.\n\n### Construire une attribution multi-signal\n\nLa solution pragmatique combine trois approches :\n\n**1. Segmentation GA4 par source/medium non standard**\n\n```javascript\n// Configuration GTM : tag personnalisé pour classifier le trafic AI\n// À déployer via Google Tag Manager comme Custom HTML tag\n\n(function() {\n  var referrer = document.referrer.toLowerCase();\n  \n  var aiSources = {\n    'chatgpt.com': 'chatgpt',\n    'chat.openai.com': 'chatgpt',\n    'perplexity.ai': 'perplexity',\n    'you.com': 'you_ai',\n    'phind.com': 'phind',\n    'bing.com/chat': 'bing_copilot',\n    'gemini.google.com': 'gemini',\n    'claude.ai': 'claude'\n  };\n  \n  var detectedSource = null;\n  \n  for (var domain in aiSources) {\n    if (referrer.indexOf(domain) !== -1) {\n      detectedSource = aiSources[domain];\n      break;\n    }\n  }\n  \n  // Détecter aussi les paramètres UTM spécifiques aux AI\n  var urlParams = new URLSearchParams(window.location.search);\n  var utmSource = urlParams.get('utm_source') || '';\n  \n  if (utmSource.match(/ai|chatgpt|perplexity|copilot/i)) {\n    detectedSource = utmSource;\n  }\n  \n  if (detectedSource) {\n    // Push vers dataLayer pour GA4\n    window.dataLayer = window.dataLayer || [];\n    window.dataLayer.push({\n      'event': 'ai_referral_detected',\n      'ai_source': detectedSource,\n      'landing_page': window.location.pathname,\n      'timestamp': new Date().toISOString()\n    });\n    \n    // Stocker en session pour attribution multi-page\n    sessionStorage.setItem('ai_entry_source', detectedSource);\n    sessionStorage.setItem('ai_entry_page', window.location.pathname);\n  }\n})();\n```\n\n**2. Analyse des patterns de comportement**\n\nLe trafic provenant des moteurs génératifs a des patterns comportementaux distincts du trafic organique classique. Les sessions sont généralement plus courtes, le taux de rebond plus élevé, et les pages d'entrée sont des pages deep-content plutôt que des pages hub. En construisant un segment GA4 qui isole ces patterns, vous pouvez approximer le volume de trafic AI même sans referrer explicite.\n\n**3. Corrélation temporelle**\n\nQuand votre mention rate (couche 1) augmente sur un prompt spécifique, le trafic organique vers la page correspondante devrait augmenter avec un décalage de quelques jours. Cette corrélation n'est pas une preuve de causalité, mais sur un échantillon suffisant de pages, elle devient statistiquement significative.\n\n### Scénario concret : un média B2B de 8 000 pages\n\nPrenons le cas d'un éditeur B2B spécialisé cybersécurité avec 8 000 articles indexés. Après implémentation du tag GTM ci-dessus sur l'ensemble du site :\n\n- **Mois 1** : le tag détecte 340 sessions avec referrer Perplexity, 180 avec referrer ChatGPT, 45 avec Phind. Total identifié : 565 sessions AI / mois.\n- **Mois 2** : en croisant avec les données de la couche 1 (monitoring de 200 prompts métier), l'équipe constate que 23 pages concentrent 78% du trafic AI identifié. Ce sont des guides techniques longs (2500+ mots) avec des données structurées Article et des auteurs identifiés.\n- **Mois 3** : en appliquant l'analyse de patterns comportementaux au trafic organique Google non attribué, l'équipe estime un trafic AI \"invisible\" supplémentaire de 1 200 à 1 800 sessions — provenant d'AI Overviews où le referrer se confond avec le trafic organique classique.\n\nTotal estimé du trafic AI : 1 800 à 2 400 sessions/mois. Soit environ 3% du trafic organique total. Modeste en volume, mais concentré sur des pages à forte intention commerciale (guides comparatifs, évaluations d'outils).\n\n## Couche 4 : Engagement Depth — mesurer ce que le visiteur AI fait vraiment\n\nUne session issue d'une réponse AI n'a pas la même valeur qu'une session organique classique. La couche 4 mesure la qualité de l'engagement post-clic spécifiquement pour le trafic AI.\n\n### Métriques d'engagement différenciées\n\nLes KPIs standard (pages/session, durée, taux de rebond) ne suffisent pas. Pour le trafic GEO, vous devez mesurer :\n\n- **Scroll depth pondéré** : est-ce que le visiteur lit au-delà du paragraphe cité par l'AI ?\n- **Interaction secondaire** : clic sur un CTA, visite d'une page pricing, téléchargement de ressource\n- **Retour direct** : le visiteur revient-il dans les 7 jours via un accès direct (signe de mémorisation de marque)\n\nL'hypothèse à tester : le trafic AI arrive avec un niveau de pré-qualification supérieur (l'utilisateur a déjà lu un résumé de votre contenu dans la réponse AI) mais un engagement initial plus faible (il a déjà obtenu une partie de la réponse). Le vrai signal de valeur est la conversion vers une action secondaire — inscription newsletter, demande de démo, ajout au panier.\n\n### Implémentation via GA4 custom events\n\nDans GA4, créez des événements personnalisés qui se déclenchent uniquement pour les sessions identifiées comme \"AI referral\" via le tag de la couche 3 :\n\n```javascript\n// Trigger conditionnel GA4 : engagement avancé pour sessions AI uniquement\n// À utiliser avec le sessionStorage posé par le tag de la couche 3\n\n(function() {\n  var aiSource = sessionStorage.getItem('ai_entry_source');\n  if (!aiSource) return; // Pas une session AI, on ne tracke rien de plus\n  \n  // 1. Scroll depth tracking granulaire\n  var scrollThresholds = [25, 50, 75, 90];\n  var firedThresholds = new Set();\n  \n  window.addEventListener('scroll', function() {\n    var scrollPercent = Math.round(\n      (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100\n    );\n    \n    scrollThresholds.forEach(function(threshold) {\n      if (scrollPercent >= threshold && !firedThresholds.has(threshold)) {\n        firedThresholds.add(threshold);\n        gtag('event', 'ai_visitor_scroll', {\n          'ai_source': aiSource,\n          'scroll_depth': threshold,\n          'page_path': window.location.pathname\n        });\n      }\n    });\n  });\n  \n  // 2. Tracking des interactions à forte valeur\n  document.addEventListener('click', function(e) {\n    var target = e.target.closest('a, button');\n    if (!target) return;\n    \n    var href = target.getAttribute('href') || '';\n    var isHighValue = (\n      href.includes('/pricing') ||\n      href.includes('/demo') ||\n      href.includes('/signup') ||\n      href.includes('/contact') ||\n      target.classList.contains('cta-primary')\n    );\n    \n    if (isHighValue) {\n      gtag('event', 'ai_visitor_high_value_click', {\n        'ai_source': aiSource,\n        'click_target': href || target.textContent.trim().substring(0, 50),\n        'entry_page': sessionStorage.getItem('ai_entry_page'),\n        'pages_viewed': history.length\n      });\n    }\n  });\n  \n  // 3. Temps passé qualifié (au-delà de 30s = engagement réel)\n  setTimeout(function() {\n    gtag('event', 'ai_visitor_engaged_time', {\n      'ai_source': aiSource,\n      'engaged_seconds': 30,\n      'page_path': window.location.pathname\n    });\n  }, 30000);\n})();\n```\n\nCette instrumentation vous permet de construire un tableau comparatif : trafic AI vs trafic organique classique vs trafic direct, sur les mêmes métriques d'engagement. C'est dans cette comparaison que réside la vraie intelligence : si vos visiteurs AI scrollent à 90% et cliquent sur la page pricing 2x plus souvent que le trafic organique moyen, vous avez un argument ROI solide pour investir davantage dans le GEO.\n\n## Couche 5 : Revenue Impact Model — connecter la visibilité AI au P&L\n\nLa couche finale est celle que votre CFO attend. Elle transforme les données des couches 1 à 4 en estimation de revenu.\n\n### Le modèle d'attribution incrémentale\n\nL'erreur classique est d'attribuer 100% du revenu d'une conversion au dernier canal touché. Pour le GEO, c'est particulièrement problématique : un utilisateur peut découvrir votre marque via une mention ChatGPT, revenir via Google organique, et convertir via un accès direct. L'approche correcte est l'attribution incrémentale.\n\nLe principe : isoler l'impact GEO en comparant le comportement de deux groupes :\n- **Groupe exposé** : utilisateurs dont la première interaction identifiée provient d'une source AI\n- **Groupe contrôle** : utilisateurs avec un profil comportemental similaire mais une première interaction organique classique\n\nLa différence de taux de conversion entre les deux groupes, multipliée par le volume du groupe exposé, donne l'impact incrémental.\n\n### Calcul pratique pour notre média B2B\n\nEn reprenant le scénario de la couche 3 :\n\n- Trafic AI estimé : 2 100 sessions/mois (médiane de l'estimation)\n- Taux de conversion vers \"demande de démo\" du trafic AI : 4,2% (mesuré via les events de la couche 4)\n- Taux de conversion baseline du trafic organique : 2,8%\n- Conversion incrémentale attribuable au GEO : (4,2% - 2,8%) × 2 100 = 29,4 demandes de démo / mois\n- Valeur moyenne d'une démo qualifiée (pipeline) : 3 200 €\n- **Impact pipeline mensuel estimé : 94 080 €**\n\nCe chiffre est une estimation, pas une certitude. Mais c'est une estimation construite sur des données mesurées à chaque couche, avec des hypothèses explicites et auditables. C'est exactement ce qu'un comité de direction peut challenger et accepter.\n\n### Les limites honnêtes de ce modèle\n\nLe modèle 5 couches a des faiblesses qu'il faut assumer :\n\n**Couche 1 : échantillonnage des prompts.** Vous ne pouvez pas monitorer tous les prompts possibles. Le choix des 100-500 prompts trackés introduit un biais de sélection. Atténuation : faire varier les prompts régulièrement et inclure des prompts \"longue traîne\" détectés via les logs Search Console.\n\n**Couche 3 : dark traffic AI.** Une part significative du trafic AI est invisible (AI Overviews, intégrations Gemini dans Android, Copilot dans Edge). L'estimation par patterns comportementaux reste approximative. Le jour où Google exposera des données de clic spécifiques aux [AI Overviews avec plus de liens](/blog/google-expands-ai-search-links-without-new-click-data-via-sejournal-mattgsouthern), cette couche gagnera en précision.\n\n**Couche 5 : attribution incrémentale vs assistée.** Le modèle mesure l'incrément de conversion, pas la totalité de la valeur. Une mention AI qui ne génère pas de clic mais installe la marque dans l'esprit de l'utilisateur (brand lift) n'est pas captée. C'est un choix conservateur — mieux vaut sous-estimer le ROI que le sur-vendre.\n\n## Connecter les couches : l'architecture de données\n\nLes 5 couches ne fonctionnent que si elles partagent un identifiant commun permettant de suivre le parcours utilisateur de bout en bout. En pratique, cet identifiant est le `client_id` GA4 enrichi par les données de session AI.\n\nL'architecture cible ressemble à ceci :\n\n- **Couche 1** (AI visibility) → base de données dédiée (PostgreSQL, BigQuery) avec les résultats de monitoring des prompts, stockés par prompt × moteur × date\n- **Couches 2-4** (éligibilité, trafic, engagement) → GA4 + BigQuery Export, avec les custom events AI\n- **Couche 5** (revenue) → CRM (HubSpot, Salesforce) connecté via l'identifiant client GA4\n\nLa jointure entre la couche 1 (quelle page est citée) et les couches 3-4 (quel trafic cette page reçoit) se fait par URL. C'est pourquoi le monitoring de la couche 1 doit stocker l'URL citée, pas seulement la mention de marque.\n\nPour les équipes qui gèrent des sites de grande envergure — 10K+ pages potentiellement éligibles au grounding — l'automatisation de ce monitoring est critique. Un outil de monitoring comme Seogard peut détecter les régressions techniques (perte de données structurées, canonical cassé, page qui passe en noindex) qui affectent directement le score d'éligibilité de la couche 2. Sans cette surveillance continue, vous optimisez le GEO sur des fondations techniques potentiellement instables.\n\n## Au-delà du framework : les questions ouvertes\n\nLe modèle 5 couches n'est pas un produit fini. C'est un cadre de pensée qui doit évoluer avec la maturité des outils et des données disponibles.\n\nTrois évolutions à surveiller :\n\n**L'émergence du WebMCP** comme protocole standard de communication entre agents AI et sites web pourrait transformer la couche 3 en rendant le trafic AI explicitement identifiable. Si votre site expose un endpoint MCP, l'agent AI qui le consomme peut s'identifier proprement. C'est un sujet à suivre de près — [les implications du WebMCP](/blog/why-now-is-the-time-to-prepare-for-webmcp) dépassent largement la seule question de la mesure.\n\n**La distinction entre les trois types de problèmes AI visibility** — visibilité dans les réponses, précision des citations, et contrôle du message — nécessite des couches de mesure distinctes. Le framework présenté ici se concentre sur la visibilité et le trafic, mais la couche 2 devrait idéalement intégrer aussi un [scoring de fidélité des citations](/blog/stop-treating-ai-visibility-as-one-problem-it-s-actually-three-on-three-different-layers-via-sejournal-duaneforrester).\n\n**Le quality threshold de Google** affecte directement l'éligibilité au grounding. Les contenus générés par AI à grande échelle qui ne passent pas ce [seuil de qualité](/blog/google-s-quality-threshold-is-quietly-killing-scaled-ai-content-via-sejournal-taylordanrw) sont aussi ceux qui ont le moins de chances d'être cités dans les AI Overviews. La couche 2 du framework doit intégrer un proxy de ce quality threshold.\n\nLe takeaway clé : arrêtez de mesurer le GEO avec un seul chiffre. Construisez les 5 couches, même imparfaitement, et vous aurez un modèle que votre direction peut comprendre et financer — et qu'un outil de monitoring comme Seogard peut alimenter en continu sur la couche technique.","https://seogard.io/blog/the-5-layer-framework-for-measuring-geo-performance","Actualités SEO","2026-05-18T18:03:17.464Z","2026-05-18","Les dashboards d'AI visibility ne suffisent pas à prouver le ROI du GEO. Voici un modèle de mesure en 5 couches crédible et actionable.","\u003Cp>La plupart des équipes SEO qui investissent dans le GEO (Generative Engine Optimization) mesurent aujourd'hui une seule chose : la présence ou l'absence de leur marque dans les réponses AI. C'est comme mesurer la performance d'un e-commerce en comptant le nombre de fois où la vitrine est allumée. Le vrai problème n'est pas la visibilité — c'est le chemin entre une mention dans une réponse ChatGPT et une conversion attribuable dans votre CRM.\u003C/p>\n\u003Ch2>Pourquoi les dashboards d'AI visibility créent une illusion de mesure\u003C/h2>\n\u003Cp>Les outils qui trackent la \"visibilité AI\" — apparition dans les AI Overviews de Google, citations dans ChatGPT, mentions dans Perplexity — répondent à une question binaire : êtes-vous mentionné, oui ou non ? C'est une couche nécessaire mais radicalement insuffisante.\u003C/p>\n\u003Cp>Le problème structurel est triple.\u003C/p>\n\u003Cp>\u003Cstrong>Absence de données de clic.\u003C/strong> Google ne fournit toujours pas de données de clic spécifiques aux AI Overviews dans Search Console. Le rapport de performance agrège les impressions et clics sans distinguer un clic classique d'un clic provenant d'une réponse générée. Bing a commencé à exposer certaines métriques via le \u003Ca href=\"/blog/bing-reveals-what-grounding-means-for-ai-search-visibility-via-sejournal-mattgsouthern\">concept de \"grounding\"\u003C/a>, mais la granularité reste faible.\u003C/p>\n\u003Cp>\u003Cstrong>Fragmentation des moteurs génératifs.\u003C/strong> Votre contenu peut être cité par ChatGPT via Bing, par Perplexity via son propre index, par Google AI Overviews, par Gemini dans Google Workspace. Chaque surface a ses propres règles de citation, son propre taux de clic, son propre profil d'utilisateur. Agréger tout ça dans un score unique de \"AI visibility\" revient à additionner des impressions TV et des clics display.\u003C/p>\n\u003Cp>\u003Cstrong>Confusion entre citation et influence.\u003C/strong> Une mention de votre marque dans une réponse AI n'implique pas que l'utilisateur a cliqué, ni qu'il a retenu votre marque, ni qu'il a converti. La corrélation entre \"être cité\" et \"générer du revenu\" est non prouvée dans la majorité des cas.\u003C/p>\n\u003Cp>C'est exactement pourquoi un framework multi-couches est indispensable : chaque couche répond à une question différente, avec des données différentes, et un niveau de confiance différent.\u003C/p>\n\u003Ch2>Couche 1 : AI Visibility Index — mesurer la présence brute\u003C/h2>\n\u003Cp>La première couche est la plus simple et la plus répandue : détecter si votre contenu ou votre marque apparaît dans les réponses génératives. C'est le socle sans lequel rien d'autre ne peut être mesuré.\u003C/p>\n\u003Ch3>Ce qu'il faut tracker concrètement\u003C/h3>\n\u003Cp>Pas juste \"est-ce qu'on apparaît\", mais avec quelle fréquence, sur quels types de requêtes, et avec quel positionnement dans la réponse (source primaire citée vs mention secondaire vs absence).\u003C/p>\n\u003Cp>Voici un script Node.js qui interroge périodiquement un ensemble de prompts sur l'API Perplexity et stocke les résultats pour analyse temporelle :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> Anthropic \u003C/span>\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"@anthropic-ai/sdk\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">interface\u003C/span>\u003Cspan style=\"color:#B392F0\"> VisibilityCheck\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  prompt\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  engine\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  brandMentioned\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> boolean\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  position\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"primary_source\"\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"secondary_mention\"\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"absent\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  citationUrl\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#F97583\"> |\u003C/span>\u003Cspan style=\"color:#79B8FF\"> null\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  checkedAt\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">async\u003C/span>\u003Cspan style=\"color:#F97583\"> function\u003C/span>\u003Cspan style=\"color:#B392F0\"> checkPerplexityVisibility\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  prompts\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">[],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  brand\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFAB70\">  apiKey\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#B392F0\"> Promise\u003C/span>\u003Cspan style=\"color:#E1E4E8\">&#x3C;\u003C/span>\u003Cspan style=\"color:#B392F0\">VisibilityCheck\u003C/span>\u003Cspan style=\"color:#E1E4E8\">[]> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> results\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#B392F0\"> VisibilityCheck\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\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> prompt\u003C/span>\u003Cspan style=\"color:#F97583\"> of\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> prompts) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> response\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#B392F0\"> fetch\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"https://api.perplexity.ai/chat/completions\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      method: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"POST\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      headers: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        Authorization: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">`Bearer ${\u003C/span>\u003Cspan style=\"color:#E1E4E8\">apiKey\u003C/span>\u003Cspan style=\"color:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        \"Content-Type\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"application/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\">      body: \u003C/span>\u003Cspan style=\"color:#79B8FF\">JSON\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        model: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"llama-3.1-sonar-large-128k-online\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        messages: [{ role: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"user\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, content: prompt }],\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\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> data\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> response.\u003C/span>\u003Cspan style=\"color:#B392F0\">json\u003C/span>\u003Cspan style=\"color:#E1E4E8\">();\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> answer\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data.choices?.[\u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]?.message?.content \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> citations\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">[] \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> data.citations \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> brandRegex\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#F97583\"> new\u003C/span>\u003Cspan style=\"color:#B392F0\"> RegExp\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(brand, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"gi\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> mentioned\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> brandRegex.\u003C/span>\u003Cspan style=\"color:#B392F0\">test\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(answer);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> citationUrl\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> citations.\u003C/span>\u003Cspan style=\"color:#B392F0\">find\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">c\u003C/span>\u003Cspan style=\"color:#F97583\">:\u003C/span>\u003Cspan style=\"color:#79B8FF\"> string\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      c.\u003C/span>\u003Cspan style=\"color:#B392F0\">toLowerCase\u003C/span>\u003Cspan style=\"color:#E1E4E8\">().\u003C/span>\u003Cspan style=\"color:#B392F0\">includes\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(brand.\u003C/span>\u003Cspan style=\"color:#B392F0\">toLowerCase\u003C/span>\u003Cspan style=\"color:#E1E4E8\">())\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    ) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#79B8FF\"> null\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    results.\u003C/span>\u003Cspan style=\"color:#B392F0\">push\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      prompt,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      engine: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"perplexity\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      brandMentioned: mentioned,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      position: citationUrl\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        ?\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"primary_source\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        :\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> mentioned\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        ?\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"secondary_mention\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        :\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"absent\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      citationUrl,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      checkedAt: \u003C/span>\u003Cspan style=\"color:#F97583\">new\u003C/span>\u003Cspan style=\"color:#B392F0\"> Date\u003C/span>\u003Cspan style=\"color:#E1E4E8\">().\u003C/span>\u003Cspan style=\"color:#B392F0\">toISOString\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  return\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> results;\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\">// Usage avec un set de prompts métier\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">const\u003C/span>\u003Cspan style=\"color:#79B8FF\"> prompts\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">  \"Quel est le meilleur outil de monitoring SEO technique ?\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">  \"Comment détecter une régression de meta descriptions à grande échelle ?\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">  \"Comparatif des outils de détection de soft 404\"\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:#B392F0\">checkPerplexityVisibility\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(prompts, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"seogard\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, process.env.\u003C/span>\u003Cspan style=\"color:#79B8FF\">PERPLEXITY_API_KEY\u003C/span>\u003Cspan style=\"color:#F97583\">!\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  .\u003C/span>\u003Cspan style=\"color:#B392F0\">then\u003C/span>\u003Cspan style=\"color:#E1E4E8\">((\u003C/span>\u003Cspan style=\"color:#FFAB70\">results\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">=>\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> console.\u003C/span>\u003Cspan style=\"color:#B392F0\">log\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">JSON\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(results, \u003C/span>\u003Cspan style=\"color:#79B8FF\">null\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)));\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Ce type de monitoring doit tourner de manière régulière (quotidienne ou hebdomadaire) pour capter les variations temporelles. Les réponses des LLM ne sont pas déterministes : une même requête peut citer votre marque un jour et l'omettre le lendemain.\u003C/p>\n\u003Ch3>Métriques de cette couche\u003C/h3>\n\u003Cul>\n\u003Cli>\u003Cstrong>AI Mention Rate\u003C/strong> : pourcentage de prompts trackés où la marque est mentionnée\u003C/li>\n\u003Cli>\u003Cstrong>Primary Source Rate\u003C/strong> : pourcentage de mentions avec lien direct en citation\u003C/li>\n\u003Cli>\u003Cstrong>Volatilité\u003C/strong> : écart-type du mention rate sur une fenêtre de 30 jours\u003C/li>\n\u003C/ul>\n\u003Cp>Ces métriques sont détaillées dans \u003Ca href=\"/blog/8-geo-metrics-to-track-in-2026\">les 8 KPIs GEO à suivre en 2026\u003C/a>. La couche 1 correspond aux métriques de \"présence\" — nécessaires mais pas suffisantes.\u003C/p>\n\u003Ch2>Couche 2 : Content Eligibility Score — qualifier ce qui peut être cité\u003C/h2>\n\u003Cp>La visibilité AI ne tombe pas du ciel. Elle dépend d'un ensemble de facteurs techniques et sémantiques qui déterminent si votre contenu est \"éligible\" à la citation par un moteur génératif. Cette couche mesure votre degré de préparation.\u003C/p>\n\u003Ch3>Les signaux d'éligibilité technique\u003C/h3>\n\u003Cp>Google a publié un \u003Ca href=\"https://developers.google.com/search/docs/appearance/ai-overviews\">guide officiel sur l'optimisation pour les fonctionnalités d'IA générative\u003C/a> qui confirme que les mêmes fondamentaux techniques (indexabilité, données structurées, contenu de qualité) restent le socle. Mais le GEO ajoute des exigences spécifiques.\u003C/p>\n\u003Cp>Le \"grounding\" — le processus par lequel un LLM ancre sa réponse dans une source vérifiable — favorise les contenus qui présentent certaines caractéristiques structurelles :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Réponses directes et factuelles\u003C/strong> dans les premiers paragraphes (pattern \"inverted pyramid\")\u003C/li>\n\u003Cli>\u003Cstrong>Données structurées\u003C/strong> exploitables (Schema.org Article, FAQPage malgré la \u003Ca href=\"/blog/google-to-no-longer-support-faq-rich-results\">fin des rich results FAQ\u003C/a>, HowTo)\u003C/li>\n\u003Cli>\u003Cstrong>Autorité topicale\u003C/strong> vérifiable (auteurs identifiés, citations vers des sources primaires)\u003C/li>\n\u003Cli>\u003Cstrong>Fraîcheur du contenu\u003C/strong> signalée par datePublished/dateModified\u003C/li>\n\u003C/ul>\n\u003Cp>Voici un audit automatisé qui vérifie l'éligibilité GEO d'une page :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> requests\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> bs4 \u003C/span>\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> BeautifulSoup\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> json\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> datetime \u003C/span>\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> datetime, timedelta\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\"> audit_geo_eligibility\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(url: \u003C/span>\u003Cspan style=\"color:#79B8FF\">str\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) -> \u003C/span>\u003Cspan style=\"color:#79B8FF\">dict\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"\"\"Audite l'éligibilité GEO d'une page sur les critères techniques clés.\"\"\"\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\"> requests.get(url, \u003C/span>\u003Cspan style=\"color:#FFAB70\">headers\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        \"User-Agent\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"Mozilla/5.0 (compatible; GEOAuditBot/1.0)\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    })\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    soup \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> BeautifulSoup(response.text, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"html.parser\"\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\">    score \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 0\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    findings \u003C/span>\u003Cspan style=\"color:#F97583\">=\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:#6A737D\">    # 1. Vérifier la présence de Schema.org JSON-LD\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    ld_scripts \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find_all(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"script\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">type\u003C/span>\u003Cspan style=\"color:#F97583\">=\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\">    schemas \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> []\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> script \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> ld_scripts:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        try\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            data \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> json.loads(script.string)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            schemas.append(data)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        except\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> json.JSONDecodeError:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            findings.append(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"WARN: JSON-LD invalide détecté\"\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\">    has_article_schema \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> any\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        d.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"@type\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"Article\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"NewsArticle\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"TechArticle\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> d \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> schemas\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    )\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> has_article_schema:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        score \u003C/span>\u003Cspan style=\"color:#F97583\">+=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 20\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    else\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        findings.append(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"FAIL: Pas de schema Article/NewsArticle\"\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:#6A737D\">    # 2. Vérifier dateModified &#x3C; 90 jours\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> schema \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> schemas:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        date_mod \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> schema.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"dateModified\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> date_mod:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">            try\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">                mod_date \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> datetime.fromisoformat(date_mod.replace(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"Z\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"+00:00\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">                if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (datetime.now(mod_date.tzinfo) \u003C/span>\u003Cspan style=\"color:#F97583\">-\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> mod_date) \u003C/span>\u003Cspan style=\"color:#F97583\">&#x3C;\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> timedelta(\u003C/span>\u003Cspan style=\"color:#FFAB70\">days\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\">90\u003C/span>\u003Cspan style=\"color:#E1E4E8\">):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">                    score \u003C/span>\u003Cspan style=\"color:#F97583\">+=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 15\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">                else\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">                    findings.append(\u003C/span>\u003Cspan style=\"color:#F97583\">f\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"WARN: dateModified > 90j (\u003C/span>\u003Cspan style=\"color:#79B8FF\">{\u003C/span>\u003Cspan style=\"color:#E1E4E8\">date_mod\u003C/span>\u003Cspan style=\"color:#79B8FF\">}\u003C/span>\u003Cspan style=\"color:#9ECBFF\">)\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">            except\u003C/span>\u003Cspan style=\"color:#79B8FF\"> ValueError\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">                findings.append(\u003C/span>\u003Cspan style=\"color:#F97583\">f\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"WARN: dateModified non parseable (\u003C/span>\u003Cspan style=\"color:#79B8FF\">{\u003C/span>\u003Cspan style=\"color:#E1E4E8\">date_mod\u003C/span>\u003Cspan style=\"color:#79B8FF\">}\u003C/span>\u003Cspan style=\"color:#9ECBFF\">)\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # 3. Réponse directe dans les 150 premiers mots\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    main_content \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"main\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">or\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"article\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">or\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"body\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> main_content:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        first_paras \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> main_content.find_all(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"p\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)[:\u003C/span>\u003Cspan style=\"color:#79B8FF\">3\u003C/span>\u003Cspan style=\"color:#E1E4E8\">]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        first_text \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \" \"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">.join(p.get_text() \u003C/span>\u003Cspan style=\"color:#F97583\">for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> p \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> first_paras)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        word_count \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> len\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(first_text.split())\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> word_count \u003C/span>\u003Cspan style=\"color:#F97583\">>=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 40\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            score \u003C/span>\u003Cspan style=\"color:#F97583\">+=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 15\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">            # Vérifier la présence de faits/chiffres dans les premiers paragraphes\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">            import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> re\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            has_numbers \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> bool\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(re.search(\u003C/span>\u003Cspan style=\"color:#F97583\">r\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'\u003C/span>\u003Cspan style=\"color:#79B8FF\">\\d\u003C/span>\u003Cspan style=\"color:#F97583\">+\u003C/span>\u003Cspan style=\"color:#79B8FF\">[%$€]\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#79B8FF\">\\d\u003C/span>\u003Cspan style=\"color:#F97583\">+\u003C/span>\u003Cspan style=\"color:#79B8FF\">\\s\u003C/span>\u003Cspan style=\"color:#F97583\">*\u003C/span>\u003Cspan style=\"color:#79B8FF\">(\u003C/span>\u003Cspan style=\"color:#DBEDFF\">pages\u003C/span>\u003Cspan style=\"color:#F97583\">?|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">URLs\u003C/span>\u003Cspan style=\"color:#F97583\">?|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">requêtes\u003C/span>\u003Cspan style=\"color:#F97583\">?\u003C/span>\u003Cspan style=\"color:#79B8FF\">)\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, first_text))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">            if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> has_numbers:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">                score \u003C/span>\u003Cspan style=\"color:#F97583\">+=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 10\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">                findings.append(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"OK: Données factuelles dans l'intro\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        else\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            findings.append(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"WARN: Intro trop courte pour le grounding\"\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:#6A737D\">    # 4. Vérifier les headers structurés (H2/H3)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    h2_count \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> len\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(soup.find_all(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"h2\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    h3_count \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> len\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(soup.find_all(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"h3\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> h2_count \u003C/span>\u003Cspan style=\"color:#F97583\">>=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 3\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        score \u003C/span>\u003Cspan style=\"color:#F97583\">+=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 15\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> h3_count \u003C/span>\u003Cspan style=\"color:#F97583\">>=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 2\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        score \u003C/span>\u003Cspan style=\"color:#F97583\">+=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 5\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # 5. Auteur identifié\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    author_schema \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> any\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(d.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"author\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> d \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> schemas)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    author_tag \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find(\u003C/span>\u003Cspan style=\"color:#FFAB70\">attrs\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">{\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"rel\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"author\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">}) \u003C/span>\u003Cspan style=\"color:#F97583\">or\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find(\u003C/span>\u003Cspan style=\"color:#FFAB70\">class_\u003C/span>\u003Cspan style=\"color:#F97583\">=lambda\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> c: c \u003C/span>\u003Cspan style=\"color:#F97583\">and\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"author\"\u003C/span>\u003Cspan style=\"color:#F97583\"> in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> c.lower() \u003C/span>\u003Cspan style=\"color:#F97583\">if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> c \u003C/span>\u003Cspan style=\"color:#F97583\">else\u003C/span>\u003Cspan style=\"color:#79B8FF\"> False\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> author_schema \u003C/span>\u003Cspan style=\"color:#F97583\">or\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> author_tag:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        score \u003C/span>\u003Cspan style=\"color:#F97583\">+=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 10\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        findings.append(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"OK: Auteur identifié\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    else\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        findings.append(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"FAIL: Pas d'auteur identifiable\"\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:#6A737D\">    # 6. Canonical et indexabilité\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    canonical \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"link\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">rel\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"canonical\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    robots_meta \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> soup.find(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"meta\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">attrs\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">{\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"name\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"robots\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">})\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> canonical \u003C/span>\u003Cspan style=\"color:#F97583\">and\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> robots_meta:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        robots_content \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> robots_meta.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"content\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        if\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> \"noindex\"\u003C/span>\u003Cspan style=\"color:#F97583\"> in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> robots_content:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            score \u003C/span>\u003Cspan style=\"color:#F97583\">-=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> 50\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">            findings.append(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"CRITICAL: Page en noindex\"\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:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        \"url\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: url,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        \"geo_eligibility_score\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">min\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(score, \u003C/span>\u003Cspan style=\"color:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        \"findings\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: findings,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        \"schema_types\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: [d.get(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"@type\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> d \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> schemas],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3>Le lien entre éligibilité et visibilité\u003C/h3>\n\u003Cp>L'intérêt de cette couche est de mesurer l'écart entre votre potentiel d'éligibilité et votre visibilité réelle (couche 1). Un score d'éligibilité élevé avec une visibilité basse pointe vers un problème d'autorité ou de couverture topicale. Une visibilité haute avec une éligibilité basse signale que vous bénéficiez probablement de la notoriété de marque — situation fragile que n'importe quel concurrent mieux structuré peut renverser.\u003C/p>\n\u003Cp>Ce type d'audit technique rejoint les recommandations du \u003Ca href=\"/blog/the-tech-seo-audit-for-the-ai-search-era-how-to-maximize-your-ai-visibility-via-sejournal-jetoctopus\">guide d'audit tech SEO pour l'ère AI\u003C/a>, mais avec un focus spécifique sur les signaux de grounding.\u003C/p>\n\u003Ch2>Couche 3 : Traffic Attribution — tracer le chemin du clic AI\u003C/h2>\n\u003Cp>C'est la couche la plus douloureuse. Les moteurs génératifs cassent le modèle d'attribution classique basé sur le referrer HTTP.\u003C/p>\n\u003Ch3>Le problème technique\u003C/h3>\n\u003Cp>Quand un utilisateur clique sur un lien dans une réponse de ChatGPT, le referrer est généralement \u003Ccode>https://chatgpt.com\u003C/code>. Quand il clique dans un AI Overview de Google, le referrer reste \u003Ccode>https://www.google.com\u003C/code> — indistinguable d'un clic organique classique. Perplexity envoie son propre referrer, mais GA4 ne le catégorise pas automatiquement comme un canal dédié.\u003C/p>\n\u003Cp>Google a commencé à exposer le trafic provenant des assistants AI dans GA4 — un sujet couvert dans \u003Ca href=\"/blog/ga4-tracks-ai-assistant-traffic-faq-results-gone-seo-pulse-via-sejournal-mattgsouthern\">l'analyse du tracking AI assistant dans GA4\u003C/a>. Mais la couverture reste partielle.\u003C/p>\n\u003Ch3>Construire une attribution multi-signal\u003C/h3>\n\u003Cp>La solution pragmatique combine trois approches :\u003C/p>\n\u003Cp>\u003Cstrong>1. Segmentation GA4 par source/medium non standard\u003C/strong>\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Configuration GTM : tag personnalisé pour classifier le trafic AI\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// À déployer via Google Tag Manager comme Custom HTML tag\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#F97583\">function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> referrer \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> document.referrer.\u003C/span>\u003Cspan style=\"color:#B392F0\">toLowerCase\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:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> aiSources \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'chatgpt.com'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'chatgpt'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'chat.openai.com'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'chatgpt'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'perplexity.ai'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'perplexity'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'you.com'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'you_ai'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'phind.com'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'phind'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'bing.com/chat'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'bing_copilot'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'gemini.google.com'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'gemini'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    'claude.ai'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'claude'\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:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> detectedSource \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> null\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:#F97583\">  for\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:#F97583\">var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> domain \u003C/span>\u003Cspan style=\"color:#F97583\">in\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> aiSources) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (referrer.\u003C/span>\u003Cspan style=\"color:#B392F0\">indexOf\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(domain) \u003C/span>\u003Cspan style=\"color:#F97583\">!==\u003C/span>\u003Cspan style=\"color:#F97583\"> -\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\">      detectedSource \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> aiSources[domain];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">      break\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">  // Détecter aussi les paramètres UTM spécifiques aux AI\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> urlParams \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> new\u003C/span>\u003Cspan style=\"color:#B392F0\"> URLSearchParams\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(window.location.search);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> utmSource \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> urlParams.\u003C/span>\u003Cspan style=\"color:#B392F0\">get\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'utm_source'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (utmSource.\u003C/span>\u003Cspan style=\"color:#B392F0\">match\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#DBEDFF\">ai\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">chatgpt\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">perplexity\u003C/span>\u003Cspan style=\"color:#F97583\">|\u003C/span>\u003Cspan style=\"color:#DBEDFF\">copilot\u003C/span>\u003Cspan style=\"color:#9ECBFF\">/\u003C/span>\u003Cspan style=\"color:#F97583\">i\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    detectedSource \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> utmSource;\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:#F97583\">  if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (detectedSource) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    // Push vers dataLayer pour GA4\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    window.dataLayer \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> window.dataLayer \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    window.dataLayer.\u003C/span>\u003Cspan style=\"color:#B392F0\">push\u003C/span>\u003Cspan style=\"color:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'event'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_referral_detected'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'ai_source'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: detectedSource,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'landing_page'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: window.location.pathname,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'timestamp'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#F97583\">new\u003C/span>\u003Cspan style=\"color:#B392F0\"> Date\u003C/span>\u003Cspan style=\"color:#E1E4E8\">().\u003C/span>\u003Cspan style=\"color:#B392F0\">toISOString\u003C/span>\u003Cspan style=\"color:#E1E4E8\">()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    // Stocker en session pour attribution multi-page\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    sessionStorage.\u003C/span>\u003Cspan style=\"color:#B392F0\">setItem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_entry_source'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, detectedSource);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    sessionStorage.\u003C/span>\u003Cspan style=\"color:#B392F0\">setItem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_entry_page'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, window.location.pathname);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">})();\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>\u003Cstrong>2. Analyse des patterns de comportement\u003C/strong>\u003C/p>\n\u003Cp>Le trafic provenant des moteurs génératifs a des patterns comportementaux distincts du trafic organique classique. Les sessions sont généralement plus courtes, le taux de rebond plus élevé, et les pages d'entrée sont des pages deep-content plutôt que des pages hub. En construisant un segment GA4 qui isole ces patterns, vous pouvez approximer le volume de trafic AI même sans referrer explicite.\u003C/p>\n\u003Cp>\u003Cstrong>3. Corrélation temporelle\u003C/strong>\u003C/p>\n\u003Cp>Quand votre mention rate (couche 1) augmente sur un prompt spécifique, le trafic organique vers la page correspondante devrait augmenter avec un décalage de quelques jours. Cette corrélation n'est pas une preuve de causalité, mais sur un échantillon suffisant de pages, elle devient statistiquement significative.\u003C/p>\n\u003Ch3>Scénario concret : un média B2B de 8 000 pages\u003C/h3>\n\u003Cp>Prenons le cas d'un éditeur B2B spécialisé cybersécurité avec 8 000 articles indexés. Après implémentation du tag GTM ci-dessus sur l'ensemble du site :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Mois 1\u003C/strong> : le tag détecte 340 sessions avec referrer Perplexity, 180 avec referrer ChatGPT, 45 avec Phind. Total identifié : 565 sessions AI / mois.\u003C/li>\n\u003Cli>\u003Cstrong>Mois 2\u003C/strong> : en croisant avec les données de la couche 1 (monitoring de 200 prompts métier), l'équipe constate que 23 pages concentrent 78% du trafic AI identifié. Ce sont des guides techniques longs (2500+ mots) avec des données structurées Article et des auteurs identifiés.\u003C/li>\n\u003Cli>\u003Cstrong>Mois 3\u003C/strong> : en appliquant l'analyse de patterns comportementaux au trafic organique Google non attribué, l'équipe estime un trafic AI \"invisible\" supplémentaire de 1 200 à 1 800 sessions — provenant d'AI Overviews où le referrer se confond avec le trafic organique classique.\u003C/li>\n\u003C/ul>\n\u003Cp>Total estimé du trafic AI : 1 800 à 2 400 sessions/mois. Soit environ 3% du trafic organique total. Modeste en volume, mais concentré sur des pages à forte intention commerciale (guides comparatifs, évaluations d'outils).\u003C/p>\n\u003Ch2>Couche 4 : Engagement Depth — mesurer ce que le visiteur AI fait vraiment\u003C/h2>\n\u003Cp>Une session issue d'une réponse AI n'a pas la même valeur qu'une session organique classique. La couche 4 mesure la qualité de l'engagement post-clic spécifiquement pour le trafic AI.\u003C/p>\n\u003Ch3>Métriques d'engagement différenciées\u003C/h3>\n\u003Cp>Les KPIs standard (pages/session, durée, taux de rebond) ne suffisent pas. Pour le trafic GEO, vous devez mesurer :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Scroll depth pondéré\u003C/strong> : est-ce que le visiteur lit au-delà du paragraphe cité par l'AI ?\u003C/li>\n\u003Cli>\u003Cstrong>Interaction secondaire\u003C/strong> : clic sur un CTA, visite d'une page pricing, téléchargement de ressource\u003C/li>\n\u003Cli>\u003Cstrong>Retour direct\u003C/strong> : le visiteur revient-il dans les 7 jours via un accès direct (signe de mémorisation de marque)\u003C/li>\n\u003C/ul>\n\u003Cp>L'hypothèse à tester : le trafic AI arrive avec un niveau de pré-qualification supérieur (l'utilisateur a déjà lu un résumé de votre contenu dans la réponse AI) mais un engagement initial plus faible (il a déjà obtenu une partie de la réponse). Le vrai signal de valeur est la conversion vers une action secondaire — inscription newsletter, demande de démo, ajout au panier.\u003C/p>\n\u003Ch3>Implémentation via GA4 custom events\u003C/h3>\n\u003Cp>Dans GA4, créez des événements personnalisés qui se déclenchent uniquement pour les sessions identifiées comme \"AI referral\" via le tag de la couche 3 :\u003C/p>\n\u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// Trigger conditionnel GA4 : engagement avancé pour sessions AI uniquement\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">// À utiliser avec le sessionStorage posé par le tag de la couche 3\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#F97583\">function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> aiSource \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> sessionStorage.\u003C/span>\u003Cspan style=\"color:#B392F0\">getItem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_entry_source'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:#F97583\">!\u003C/span>\u003Cspan style=\"color:#E1E4E8\">aiSource) \u003C/span>\u003Cspan style=\"color:#F97583\">return\u003C/span>\u003Cspan style=\"color:#E1E4E8\">; \u003C/span>\u003Cspan style=\"color:#6A737D\">// Pas une session AI, on ne tracke rien de plus\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">  // 1. Scroll depth tracking granulaire\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> scrollThresholds \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:#79B8FF\">25\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">75\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">90\u003C/span>\u003Cspan style=\"color:#E1E4E8\">];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">  var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> firedThresholds \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#F97583\"> new\u003C/span>\u003Cspan style=\"color:#B392F0\"> Set\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\">  window.\u003C/span>\u003Cspan style=\"color:#B392F0\">addEventListener\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'scroll'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#F97583\">function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> scrollPercent \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> Math.\u003C/span>\u003Cspan style=\"color:#B392F0\">round\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      (window.scrollY \u003C/span>\u003Cspan style=\"color:#F97583\">/\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (document.body.scrollHeight \u003C/span>\u003Cspan style=\"color:#F97583\">-\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> window.innerHeight)) \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\">\u003Cspan style=\"color:#E1E4E8\">    \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    scrollThresholds.\u003C/span>\u003Cspan style=\"color:#B392F0\">forEach\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#F97583\">function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#FFAB70\">threshold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">      if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (scrollPercent \u003C/span>\u003Cspan style=\"color:#F97583\">>=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> threshold \u003C/span>\u003Cspan style=\"color:#F97583\">&#x26;&#x26;\u003C/span>\u003Cspan style=\"color:#F97583\"> !\u003C/span>\u003Cspan style=\"color:#E1E4E8\">firedThresholds.\u003C/span>\u003Cspan style=\"color:#B392F0\">has\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(threshold)) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        firedThresholds.\u003C/span>\u003Cspan style=\"color:#B392F0\">add\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(threshold);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">        gtag\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'event'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_visitor_scroll'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">          'ai_source'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: aiSource,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">          'scroll_depth'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: threshold,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">          'page_path'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: window.location.pathname\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\">  });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">  // 2. Tracking des interactions à forte valeur\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">  document.\u003C/span>\u003Cspan style=\"color:#B392F0\">addEventListener\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'click'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#F97583\">function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#FFAB70\">e\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> target \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> e.target.\u003C/span>\u003Cspan style=\"color:#B392F0\">closest\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'a, button'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:#F97583\">!\u003C/span>\u003Cspan style=\"color:#E1E4E8\">target) \u003C/span>\u003Cspan style=\"color:#F97583\">return\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:#F97583\">    var\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> href \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> target.\u003C/span>\u003Cspan style=\"color:#B392F0\">getAttribute\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'href'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> ''\u003C/span>\u003Cspan style=\"color:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    var\u003C/span>\u003Cspan style=\"color:#B392F0\"> isHighValue\u003C/span>\u003Cspan style=\"color:#F97583\"> =\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      href.\u003C/span>\u003Cspan style=\"color:#B392F0\">includes\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'/pricing'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      href.\u003C/span>\u003Cspan style=\"color:#B392F0\">includes\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'/demo'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      href.\u003C/span>\u003Cspan style=\"color:#B392F0\">includes\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'/signup'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      href.\u003C/span>\u003Cspan style=\"color:#B392F0\">includes\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'/contact'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      target.classList.\u003C/span>\u003Cspan style=\"color:#B392F0\">contains\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'cta-primary'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> (isHighValue) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">      gtag\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'event'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_visitor_high_value_click'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'ai_source'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: aiSource,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'click_target'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: href \u003C/span>\u003Cspan style=\"color:#F97583\">||\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> target.textContent.\u003C/span>\u003Cspan style=\"color:#B392F0\">trim\u003C/span>\u003Cspan style=\"color:#E1E4E8\">().\u003C/span>\u003Cspan style=\"color:#B392F0\">substring\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'entry_page'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: sessionStorage.\u003C/span>\u003Cspan style=\"color:#B392F0\">getItem\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_entry_page'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        'pages_viewed'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: history.\u003C/span>\u003Cspan style=\"color:#79B8FF\">length\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\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">  // 3. Temps passé qualifié (au-delà de 30s = engagement réel)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">  setTimeout\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#F97583\">function\u003C/span>\u003Cspan style=\"color:#E1E4E8\">() {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">    gtag\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">'event'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#9ECBFF\">'ai_visitor_engaged_time'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'ai_source'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: aiSource,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'engaged_seconds'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">30\u003C/span>\u003Cspan style=\"color:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">      'page_path'\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: window.location.pathname\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>\u003Cspan style=\"color:#79B8FF\">30000\u003C/span>\u003Cspan style=\"color:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">})();\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Cette instrumentation vous permet de construire un tableau comparatif : trafic AI vs trafic organique classique vs trafic direct, sur les mêmes métriques d'engagement. C'est dans cette comparaison que réside la vraie intelligence : si vos visiteurs AI scrollent à 90% et cliquent sur la page pricing 2x plus souvent que le trafic organique moyen, vous avez un argument ROI solide pour investir davantage dans le GEO.\u003C/p>\n\u003Ch2>Couche 5 : Revenue Impact Model — connecter la visibilité AI au P&#x26;L\u003C/h2>\n\u003Cp>La couche finale est celle que votre CFO attend. Elle transforme les données des couches 1 à 4 en estimation de revenu.\u003C/p>\n\u003Ch3>Le modèle d'attribution incrémentale\u003C/h3>\n\u003Cp>L'erreur classique est d'attribuer 100% du revenu d'une conversion au dernier canal touché. Pour le GEO, c'est particulièrement problématique : un utilisateur peut découvrir votre marque via une mention ChatGPT, revenir via Google organique, et convertir via un accès direct. L'approche correcte est l'attribution incrémentale.\u003C/p>\n\u003Cp>Le principe : isoler l'impact GEO en comparant le comportement de deux groupes :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Groupe exposé\u003C/strong> : utilisateurs dont la première interaction identifiée provient d'une source AI\u003C/li>\n\u003Cli>\u003Cstrong>Groupe contrôle\u003C/strong> : utilisateurs avec un profil comportemental similaire mais une première interaction organique classique\u003C/li>\n\u003C/ul>\n\u003Cp>La différence de taux de conversion entre les deux groupes, multipliée par le volume du groupe exposé, donne l'impact incrémental.\u003C/p>\n\u003Ch3>Calcul pratique pour notre média B2B\u003C/h3>\n\u003Cp>En reprenant le scénario de la couche 3 :\u003C/p>\n\u003Cul>\n\u003Cli>Trafic AI estimé : 2 100 sessions/mois (médiane de l'estimation)\u003C/li>\n\u003Cli>Taux de conversion vers \"demande de démo\" du trafic AI : 4,2% (mesuré via les events de la couche 4)\u003C/li>\n\u003Cli>Taux de conversion baseline du trafic organique : 2,8%\u003C/li>\n\u003Cli>Conversion incrémentale attribuable au GEO : (4,2% - 2,8%) × 2 100 = 29,4 demandes de démo / mois\u003C/li>\n\u003Cli>Valeur moyenne d'une démo qualifiée (pipeline) : 3 200 €\u003C/li>\n\u003Cli>\u003Cstrong>Impact pipeline mensuel estimé : 94 080 €\u003C/strong>\u003C/li>\n\u003C/ul>\n\u003Cp>Ce chiffre est une estimation, pas une certitude. Mais c'est une estimation construite sur des données mesurées à chaque couche, avec des hypothèses explicites et auditables. C'est exactement ce qu'un comité de direction peut challenger et accepter.\u003C/p>\n\u003Ch3>Les limites honnêtes de ce modèle\u003C/h3>\n\u003Cp>Le modèle 5 couches a des faiblesses qu'il faut assumer :\u003C/p>\n\u003Cp>\u003Cstrong>Couche 1 : échantillonnage des prompts.\u003C/strong> Vous ne pouvez pas monitorer tous les prompts possibles. Le choix des 100-500 prompts trackés introduit un biais de sélection. Atténuation : faire varier les prompts régulièrement et inclure des prompts \"longue traîne\" détectés via les logs Search Console.\u003C/p>\n\u003Cp>\u003Cstrong>Couche 3 : dark traffic AI.\u003C/strong> Une part significative du trafic AI est invisible (AI Overviews, intégrations Gemini dans Android, Copilot dans Edge). L'estimation par patterns comportementaux reste approximative. Le jour où Google exposera des données de clic spécifiques aux \u003Ca href=\"/blog/google-expands-ai-search-links-without-new-click-data-via-sejournal-mattgsouthern\">AI Overviews avec plus de liens\u003C/a>, cette couche gagnera en précision.\u003C/p>\n\u003Cp>\u003Cstrong>Couche 5 : attribution incrémentale vs assistée.\u003C/strong> Le modèle mesure l'incrément de conversion, pas la totalité de la valeur. Une mention AI qui ne génère pas de clic mais installe la marque dans l'esprit de l'utilisateur (brand lift) n'est pas captée. C'est un choix conservateur — mieux vaut sous-estimer le ROI que le sur-vendre.\u003C/p>\n\u003Ch2>Connecter les couches : l'architecture de données\u003C/h2>\n\u003Cp>Les 5 couches ne fonctionnent que si elles partagent un identifiant commun permettant de suivre le parcours utilisateur de bout en bout. En pratique, cet identifiant est le \u003Ccode>client_id\u003C/code> GA4 enrichi par les données de session AI.\u003C/p>\n\u003Cp>L'architecture cible ressemble à ceci :\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Couche 1\u003C/strong> (AI visibility) → base de données dédiée (PostgreSQL, BigQuery) avec les résultats de monitoring des prompts, stockés par prompt × moteur × date\u003C/li>\n\u003Cli>\u003Cstrong>Couches 2-4\u003C/strong> (éligibilité, trafic, engagement) → GA4 + BigQuery Export, avec les custom events AI\u003C/li>\n\u003Cli>\u003Cstrong>Couche 5\u003C/strong> (revenue) → CRM (HubSpot, Salesforce) connecté via l'identifiant client GA4\u003C/li>\n\u003C/ul>\n\u003Cp>La jointure entre la couche 1 (quelle page est citée) et les couches 3-4 (quel trafic cette page reçoit) se fait par URL. C'est pourquoi le monitoring de la couche 1 doit stocker l'URL citée, pas seulement la mention de marque.\u003C/p>\n\u003Cp>Pour les équipes qui gèrent des sites de grande envergure — 10K+ pages potentiellement éligibles au grounding — l'automatisation de ce monitoring est critique. Un outil de monitoring comme Seogard peut détecter les régressions techniques (perte de données structurées, canonical cassé, page qui passe en noindex) qui affectent directement le score d'éligibilité de la couche 2. Sans cette surveillance continue, vous optimisez le GEO sur des fondations techniques potentiellement instables.\u003C/p>\n\u003Ch2>Au-delà du framework : les questions ouvertes\u003C/h2>\n\u003Cp>Le modèle 5 couches n'est pas un produit fini. C'est un cadre de pensée qui doit évoluer avec la maturité des outils et des données disponibles.\u003C/p>\n\u003Cp>Trois évolutions à surveiller :\u003C/p>\n\u003Cp>\u003Cstrong>L'émergence du WebMCP\u003C/strong> comme protocole standard de communication entre agents AI et sites web pourrait transformer la couche 3 en rendant le trafic AI explicitement identifiable. Si votre site expose un endpoint MCP, l'agent AI qui le consomme peut s'identifier proprement. C'est un sujet à suivre de près — \u003Ca href=\"/blog/why-now-is-the-time-to-prepare-for-webmcp\">les implications du WebMCP\u003C/a> dépassent largement la seule question de la mesure.\u003C/p>\n\u003Cp>\u003Cstrong>La distinction entre les trois types de problèmes AI visibility\u003C/strong> — visibilité dans les réponses, précision des citations, et contrôle du message — nécessite des couches de mesure distinctes. Le framework présenté ici se concentre sur la visibilité et le trafic, mais la couche 2 devrait idéalement intégrer aussi un \u003Ca href=\"/blog/stop-treating-ai-visibility-as-one-problem-it-s-actually-three-on-three-different-layers-via-sejournal-duaneforrester\">scoring de fidélité des citations\u003C/a>.\u003C/p>\n\u003Cp>\u003Cstrong>Le quality threshold de Google\u003C/strong> affecte directement l'éligibilité au grounding. Les contenus générés par AI à grande échelle qui ne passent pas ce \u003Ca href=\"/blog/google-s-quality-threshold-is-quietly-killing-scaled-ai-content-via-sejournal-taylordanrw\">seuil de qualité\u003C/a> sont aussi ceux qui ont le moins de chances d'être cités dans les AI Overviews. La couche 2 du framework doit intégrer un proxy de ce quality threshold.\u003C/p>\n\u003Cp>Le takeaway clé : arrêtez de mesurer le GEO avec un seul chiffre. Construisez les 5 couches, même imparfaitement, et vous aurez un modèle que votre direction peut comprendre et financer — et qu'un outil de monitoring comme Seogard peut alimenter en continu sur la couche technique.\u003C/p>",null,14,[18,19,20,21,22],"GEO","AI search","framework","measuring","performance","Framework 5 couches pour mesurer la performance GEO","Mon May 18 2026 18:03:17 GMT+0000 (Coordinated Universal Time)",[26,40,54],{"_id":27,"slug":28,"__v":6,"author":7,"canonical":29,"category":10,"createdAt":30,"date":31,"description":32,"image":15,"imageAlt":15,"readingTime":33,"tags":34,"title":38,"updatedAt":39},"6a0d4ea4aa6b273b0cde629a","reasoning-lift-what-happens-to-brand-visibility-when-ai-thinks-harder","https://seogard.io/blog/reasoning-lift-what-happens-to-brand-visibility-when-ai-thinks-harder","2026-05-20T06:03:16.188Z","2026-05-20","Analyse technique de 200 réponses GPT-5.2 : le raisonnement élevé cite plus de sources, favorise le haut de funnel et redéfinit la visibilité de marque.",12,[35,19,36,18,37],"reasoning lift","brand visibility","LLM","Reasoning lift : impact du raisonnement IA sur la visibilité des marques","Wed May 20 2026 06:03:16 GMT+0000 (Coordinated Universal Time)",{"_id":41,"slug":42,"__v":6,"author":7,"canonical":43,"category":10,"createdAt":44,"date":31,"description":45,"image":15,"imageAlt":15,"readingTime":33,"tags":46,"title":52,"updatedAt":53},"6a0d86d3aa6b273b0c0cbec7","google-brings-ai-content-verification-to-search-via-sejournal-mattgsouthern","https://seogard.io/blog/google-brings-ai-content-verification-to-search-via-sejournal-mattgsouthern","2026-05-20T10:02:59.955Z","Google intègre SynthID à Search pour vérifier le contenu IA. Analyse technique des watermarks, impact sur le crawl et stratégies SEO concrètes.",[47,48,49,50,51],"google","synthid","ai content verification","search","seo technique","SynthID dans Search : impact technique sur le SEO","Wed May 20 2026 10:02:59 GMT+0000 (Coordinated Universal Time)",{"_id":55,"slug":56,"__v":6,"author":7,"canonical":57,"category":10,"createdAt":58,"date":31,"description":59,"image":15,"imageAlt":15,"readingTime":33,"tags":60,"title":66,"updatedAt":67},"6a0df755aa6b273b0c69952f","google-s-llms-txt-guidance-depends-on-which-product-you-ask-via-sejournal-mattgsouthern","https://seogard.io/blog/google-s-llms-txt-guidance-depends-on-which-product-you-ask-via-sejournal-mattgsouthern","2026-05-20T18:03:01.922Z","Google Search ignore llms.txt, mais Lighthouse l'audite pour l'agentic browsing. Analyse technique des contradictions et guide d'implémentation.",[61,62,63,64,65],"llms.txt","agentic browsing","Lighthouse","AI Search","Google","llms.txt : Google Search et Lighthouse se contredisent","Wed May 20 2026 18:03:01 GMT+0000 (Coordinated Universal Time)"]