Retour au Blog
Angular Development11 novembre 20268 min de lecture

Votre site JavaScript est-il invisible pour la recherche IA ? Comment le vérifier et le corriger

DR

Doug Ribeiro

8 min de lecture

Une application Angular rendue côté client a l'air complète dans un navigateur et presque vide pour tout bot qui n'exécute pas JavaScript. Avant de passer mon portfolio en pré-rendu statique, j'ai mesuré ce point de départ comme le ferait un tel crawler. Un article de blog d'un peu plus de mille mots revenait sous la forme d'un app-root vide, avec le même titre générique que partageaient toutes les pages. L'article n'existait qu'une fois Angular démarré dans un navigateur.

Après la migration, la même URL renvoie environ 1 300 mots dans le HTML initial, avec son propre titre. Ce compte inclut l'en-tête et le pied de page, mais la différence, c'est l'article entier. Le contenu lui-même n'a pas changé.

Ce que font vraiment les crawlers

Google est l'exception célèbre, et elle a trompé toute une génération d'entre nous. Sa documentation décrit trois phases : exploration, rendu, indexation. Les pages attendent dans une file jusqu'à ce qu'un Chromium headless puisse exécuter le JavaScript. Une application rendue côté client peut donc se classer sur Google, et ça nous a appris que les crawlers exécutent JavaScript. Le même guide dit pourtant toujours que le rendu côté serveur ou le pré-rendu en valent la peine, parce que tous les bots ne peuvent pas exécuter JavaScript.

La mesure que je vois citée le plus souvent pour les autres est celle de Vercel, de décembre 2024. Elle a constaté que les crawlers d'OpenAI, ClaudeBot d'Anthropic et les crawlers de Meta, ByteDance et Perplexity ne faisaient pas le rendu du JavaScript. Les crawlers de ChatGPT et de Claude téléchargeaient bien les fichiers JavaScript, mais ne les exécutaient pas. Gemini, sur l'infrastructure de Google, et AppleBot faisaient le rendu. Ces données ont presque deux ans, et je n'ai pas trouvé d'étude plus récente de même qualité. Les crawlers changent, alors vérifiez sur votre propre site et dans vos propres logs.

Le test d'une minute

Choisissez une vraie page de contenu et une courte phrase tirée de son milieu, sans ponctuation, parce que les entités HTML donnent de faux zéros. Ensuite, demandez la page comme le ferait un crawler simple. Le grep compte les lignes correspondantes, donc zéro veut dire que la phrase n'est pas dans le HTML servi. Un résultat peut venir d'un blob d'état JSON plutôt que du balisage, alors ouvrez la sortie et regardez si le compte vous surprend.

bash
# Is the content in the HTML the server sends?
curl -sL https://example.com/some-article | grep -c "a short phrase from the middle"

# Is your host or CDN treating a bot differently?
curl -sL -o /dev/null -w '%{http_code}\n' -A "GPTBot" https://example.com/some-article

# Does a page that does not exist return a real 404?
curl -sL -o /dev/null -w '%{http_code}\n' https://example.com/this-page-does-not-exist

Sur la version rendue côté client, la première commande renvoyait 0 et la troisième renvoyait 200. Cette dernière, c'est un soft 404. L'hébergement de single-page apps réécrit généralement chaque URL inconnue vers index.html, donc les bots reçoivent un statut de succès et une coquille vide pour chaque lien mort. C'est l'échec que les gens ratent, parce que la page a l'air correcte dans un navigateur, où l'application affiche un bel écran de page introuvable.

Sachez quel bot est lequel avant de toucher à robots.txt

Bloquer les bots IA, c'est souvent une seule décision prise à propos de trois choses différentes. Les fournisseurs les séparent, et la distinction détermine ce que vous perdez.

  • Entraînement : GPTBot et ClaudeBot. Les bloquer signifie que votre contenu ne devrait pas servir à entraîner des modèles.
  • Index de recherche : OAI-SearchBot et Claude-SearchBot. Si vous bloquez OAI-SearchBot, OpenAI dit que votre site n'apparaîtra pas dans les réponses de recherche de ChatGPT, même s'il peut encore apparaître comme lien de navigation. Anthropic prévient que bloquer Claude-SearchBot peut réduire votre visibilité dans ses résultats de recherche.
  • Récupération déclenchée par l'utilisateur : ChatGPT-User et Claude-User. Ceux-ci récupèrent une page parce qu'une personne l'a demandé. Anthropic dit que bloquer Claude-User peut réduire la visibilité pour la recherche dirigée par l'utilisateur. OpenAI dit que ChatGPT-User n'est pas ce qui détermine si du contenu apparaît dans la recherche, et que les règles de robots.txt peuvent ne pas s'y appliquer.

Vous pouvez donc refuser l'entraînement et rester trouvable. Voici à quoi ça ressemble. Mon propre site autorise tout, parce qu'un portfolio veut être lu, mais voici le fichier dont je partirais si je ne voulais pas nourrir l'entraînement :

text
User-agent: GPTBot
Disallow: /

User-agent: ClaudeBot
Disallow: /

User-agent: *
Allow: /

Sitemap: https://example.com/sitemap.xml

Allez lire votre robots.txt actuel maintenant. Si quelqu'un a ajouté un blocage IA général il y a quelques années, vérifiez s'il attrape aussi les bots de recherche. Vérifiez aussi tout réglage de protection contre les bots sur votre CDN, qui peut bloquer des crawlers que robots.txt autorise. Le deuxième curl ci-dessus peut détecter un blocage basé sur le user agent, mais pas un blocage basé sur l'IP.

J'ai laissé tomber llms.txt, et les données me donnent raison

llms.txt est une proposition de Jeremy Howard, datant de septembre 2024, pour un fichier Markdown qui oriente les modèles de langage vers votre contenu clé. Ce n'est pas un standard ratifié. Ça ne coûte presque rien, alors les gens l'ajoutent en espérant être cités par l'IA. Les données ne vont pas dans leur sens.

  • Ahrefs a examiné les logs serveur de 137 000 domaines, tous clients de son propre outil d'analytique, et traite donc les 28 % qui publient le fichier comme une borne haute. 97 % de ces fichiers n'ont reçu aucune requête en mai 2026.
  • SE Ranking a étudié environ 300 000 domaines et n'a trouvé aucun lien mesurable entre le fait d'avoir le fichier et le fait d'être cité.
  • Les recommandations de Google disent que vous n'avez pas besoin de nouveaux fichiers lisibles par machine ni de fichiers texte pour l'IA pour apparaître dans AI Overviews ou AI Mode. John Mueller a aussi dit que les systèmes LLM ne peuvent pas se fier à ce fichier pour distinguer les sites web entre eux.

Un contre-argument honnête. Ahrefs a trouvé GPTBot et Claude Code près du sommet des agents IA qui récupèrent ces fichiers, même si GPTBot ne représentait qu'environ 4,5 % des récupérations, et Chrome a ajouté une vérification llms.txt aux audits agentiques expérimentaux de Lighthouse. Si vous gérez un site de documentation que lisent des agents de code, le fichier peut valoir ses quelques minutes de travail. Pour un site marketing, un blog ou un portfolio, je passerais ces minutes sur le HTML. Mon site n'en a pas.

Ce que la correction a demandé sur un hébergement statique

Vous n'avez pas besoin d'un serveur Node pour ça. Mon site est sur un hébergement statique, et le pré-rendu coûte du temps de build plus une vraie contrainte : changer le contenu veut maintenant dire un rebuild et un déploiement. Angular l'intègre déjà : ajoutez @angular/ssr, mettez outputMode à static dans angular.json, et donnez à chaque route publique un mode Prerender. Les routes avec paramètres doivent déclarer leurs valeurs au moment du build, et c'est la partie qui demande réflexion :

typescript
// app.routes.server.ts (simplified)
export const serverRoutes: ServerRoute[] = [
  {
    path: 'blog/:slug',
    renderMode: RenderMode.Prerender,
    getPrerenderParams: async () => postSlugs().map(slug => ({ slug })),
  },
  { path: '**', renderMode: RenderMode.Client }, // the shell I publish as 404.html
];

Avec React, la même décision passe par un framework : Astro, Next.js, ou React Router en mode framework. L'export statique de Next.js abandonne le rendu par requête, alors vérifiez avant de le choisir. L'outil importe peu. Décidez route par route : le contenu que tout le monde peut lire reçoit du HTML au build, le contenu qui change à chaque requête reçoit du rendu serveur, et tout ce qui est derrière une connexion peut rester rendu côté client, parce qu'aucun crawler n'y arrive de toute façon.

Le build produit environ 300 pages dans quatre langues. Le rendu était la moitié facile. Voici le reste :

  • Un titre propre à la page, et une description et une URL canonique uniques sur chaque page, dans le HTML initial.
  • Des hreflang uniquement entre de vraies traductions. Une page qui se rabat sur l'anglais reçoit une canonique vers l'URL anglaise et aucune alternative.
  • Un sitemap généré au build à partir des données des articles, et un build qui échoue si les nombres d'articles ne concordent pas.
  • Une seule URL par page. Choisissez avec ou sans barre oblique finale et redirigez l'autre. Apache ajoute sa propre redirection de répertoire, alors je l'ai désactivée avec DirectorySlash Off, j'ai ajouté une réécriture vers l'index.html de chaque dossier, et j'ai laissé les listings de répertoires désactivés.
  • Un vrai statut 404. Un 404.html via ErrorDocument, pas une réécriture vers index.html.
  • Une hydratation qui ne se bat pas contre le HTML statique. Dans Angular, regardez provideClientHydration et son transfer cache. Tout ce qui dépend de la page terminée, comme défiler jusqu'à une ancre, doit attendre ApplicationRef.whenStable. Le symptôme typique est un lien qui défile avant que la section soit chargée.

Ce que le pré-rendu ne promet pas

Un HTML lisible vous permet d'être pris en compte. C'est tout ce qu'il vous apporte. Rien ici ne garantit qu'une réponse IA vous citera. Ce que je peux dire, c'est que l'échec est binaire : un contenu qu'un bot ne peut pas lire ne peut pas être cité à partir de cette récupération. Corrigez ça d'abord, parce que c'est la seule partie du débat sur la recherche IA que vous contrôlez entièrement.

Après le déploiement, lisez vos logs d'accès au lieu de deviner. Un grep sur GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, Claude-User et PerplexityBot montre qui passe et quel statut chacun reçoit. Les user agents peuvent être usurpés, alors prenez-le comme un signal approximatif.

Ouvrez votre site avec JavaScript désactivé, ou faites-lui un curl. Ce que vous voyez, c'est ce que voit une grande partie des bots qui vous intéressent.

Références

SEOAngularPrerenderingAIWeb Performance