Tech & Web
Rédigé le 11/9/2026
Modifié le 11/9/2026
3min

JavaScript et SEO : Googlebot et les robots IA reçoivent la même page

Thibaut Legrand
Thibaut Legrand
Co-fondateur - Vydera
JavaScript SEO rendu robots IA Vydera
Sommaire

Votre contenu est-il lisible sans JavaScript ?

Vydera mesure ce que chaque robot reçoit, puis corrige.

Parler à un expert

Points clés de l'article

  • 27 URLs récupérées 8 fois chacune le 27 août 2026 : 4 User-Agent, un navigateur, Googlebot, GPTBot et ClaudeBot, multipliés par 2 passes complètes, plus un rendu Chrome headless et une lecture du robots.txt
  • L'écart de mots entre Googlebot et GPTBot est de zéro sur les 20 sites servis aux quatre identités. 19 servent exactement le même nombre de mots à tout le monde, 14 à l'octet près
  • L'écart se joue sur l'accès, pas sur le contenu : 2 blocages IA corroborés sur 25 sites accessibles, nytimes.com et malt.fr. Les trois autres refus sont du pare-feu ou de la détection d'usurpation
  • Le rendu n'ajoute qu'un facteur médian de 1,13 sur les 19 sites au HTML complet, quand app.diagrams.net passe de 66 mots servis à 1 462 après exécution du JavaScript
  • Le blog FR d'Ahrefs affiche 1 174 mots visibles et embarque 137 366 mots de prose dans ses balises script : le texte est dans la réponse, il n'est pas dans le document

La phrase circule depuis deux ans dans toutes les présentations : « Google exécute le JavaScript, les moteurs IA non ». Elle est répétée partout, mesurée nulle part en français, et elle envoie chercher le problème au mauvais endroit.

Le 27 août 2026, on a récupéré 27 URLs, une par hôte, huit fois chacune : quatre User-Agent, un navigateur Chrome 126, Googlebot, GPTBot/1.1 et ClaudeBot/1.0, multipliés par deux passes complètes à 5 secondes d'intervalle. Puis une neuvième récupération dans Chrome headless pour obtenir le DOM après exécution du JavaScript, et une lecture du robots.txt.

Le résultat principal ne dit pas ce qu'on espérait, et c'est précisément ce qui le rend utile. Sur les 20 sites où les quatre User-Agent ont reçu une vraie page, l'écart de mots entre Googlebot et GPTBot est de zéro. Sur les vingt. Dix-neuf d'entre eux servent exactement le même nombre de mots à un navigateur, à Googlebot, à GPTBot et à ClaudeBot.

Le problème du JavaScript existe. Il n'est simplement pas là où on le cherche. Il se joue sur deux axes que ce relevé sépare nettement : l'accès, un 403 contre un 200, et le rendu, le HTML servi contre le DOM exécuté.

La méthode, et comment la rejouer chez vous

Seul l'en-tête User-Agent varie d'une requête à l'autre. Accept et Accept-Language sont figés, l'ordre des quatre User-Agent est tiré au sort à chaque passe, et une anomalie n'est retenue comme traitement différencié que si elle se reproduit sur la seconde passe. Cette règle-là a écarté plusieurs faux positifs.

La mesure tient en deux lignes de terminal. La première récupère la page sous l'identité de votre choix et affiche le code HTTP avec le poids exact de la réponse :

curl -s -o page.html -w 'HTTP %{http_code} · %{size_download} octets' -A 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' 'https://exemple.fr/'

La seconde retire commentaires, scripts, styles et balises du fichier récupéré, puis compte ce qui reste. Le générateur ci-dessous écrit les deux commandes pour l'URL et le robot de votre choix, plus la ligne de Chrome headless qui donne le DOM rendu et la lecture du robots.txt.

Un point de contrôle avant d'aller plus loin. Sur vydera.com/fr, cette recette rend 223 233 octets, exactement le poids que le script d'audit a enregistré. Le compte de mots, lui, est une approximation assumée : 1 740 contre 1 635 pour le script, plus strict, qui ne retient que les jetons contenant au moins une lettre. Les octets sont exacts, les mots sont indicatifs, et c'est l'écart entre deux mesures qui compte, jamais leur valeur absolue.

Premier résultat : le serveur ne regarde pas qui demande

Sur les 20 sites servis aux quatre User-Agent, seul dénominateur qui autorise une comparaison de contenu :

  • 19 servent exactement le même nombre de mots aux quatre identités
  • 14 renvoient une réponse identique à l'octet près
  • l'écart de mots entre Googlebot et GPTBot est nul sur les 20

Les cinq sites identiques en mots mais pas en octets font varier quelque chose dans leur réponse sans que le contenu bouge. Le relevé ne dit pas quoi, et on s'arrêtera au constat.

Autrement dit, l'écrasante majorité des serveurs ne fait aucune différence entre un navigateur, Googlebot et un robot IA. Le HTML est le même pour tout le monde. Voici le relevé complet, filtrable : cliquez sur le nom d'un site pour le détail des cas particuliers.

L'écart se joue sur l'accès, pas sur le contenu

Cinq des 25 sites accessibles au navigateur refusent au moins un robot. C'est déjà peu, et le chiffre honnête est plus petit encore : seuls deux de ces cinq cas sont un blocage IA au sens strict.

  • nytimes.com et malt.fr : Googlebot reçoit un 200 et une page complète, GPTBot et ClaudeBot un 403. Le robots.txt des deux sites interdit GPTBot de façon indépendante. Deux cas corroborés, stables sur les deux passes.
  • lefigaro.fr et lesechos.fr : les trois robots reçoivent un 403, Googlebot compris, quand le navigateur reçoit un 200. C'est un filtre de pare-feu sur l'en-tête User-Agent, pas une politique anti-IA. Les deux interdisent pourtant GPTBot dans leur robots.txt : la déclaration et l'application se décident à deux endroits différents.
  • doctolib.fr : le cas inverse. Un User-Agent Googlebot reçoit un 403 pendant que GPTBot passe. Envoyé depuis une adresse IP grand public, un en-tête Googlebot n'est pas Googlebot, et la vérification réelle passe par le DNS inverse. Ce refus ressemble beaucoup plus à une détection d'usurpation qu'à un blocage de Google, et il ne faut surtout pas écrire l'inverse.

La leçon opérationnelle tient en une phrase : avant de conclure qu'un site bloque les IA, regardez ce que reçoit Googlebot dans le même relevé. Sur les cinq refus observés, trois n'ont rien à voir avec une politique IA.

Deux sites servent bel et bien autre chose aux robots

lemonde.fr sert 1,81 fois plus de mots aux trois robots qu'à un navigateur : 11 245 contre 6 214, soit 1,95 Mo contre 1,02 Mo. Le chiffre est identique pour Googlebot, GPTBot et ClaudeBot, et stable d'une passe à l'autre. C'est le seul site des 20 comparables à traiter les robots différemment au niveau du contenu.

doctolib.fr va plus loin : il sert deux pages différentes à deux robots IA au même instant. GPTBot reçoit 80 892 octets contenant 529 mots de contenu éditorial, le hero « Vivez en meilleure santé ». ClaudeBot reçoit les mêmes 1 640 429 octets que le navigateur, dont le texte servi se réduit à 228 mots de pied de page. Contrôlé à la main sur deux tours supplémentaires : ce n'est pas la même page, c'est une version prérendue réservée à certains robots.

Ces deux cas prouvent que la différenciation par User-Agent fonctionne techniquement. Ils ne disent rien de sa prudence : servir un contenu qui diverge selon l'identité déclarée est exactement ce que les consignes de Google appellent du cloaking. À faire en connaissance de cause, ou pas du tout.

Le vrai écart : le HTML servi contre le DOM exécuté

C'est ici que le sujet devient un sujet. Sur les 19 sites qui servent déjà un HTML complet, l'exécution du JavaScript n'ajoute qu'un facteur médian de 1,13 sur le nombre de mots. La médiane des mots servis au premier fetch, sur les 25 sites mesurés, est de 1 027. Le HTML du premier fetch porte déjà l'essentiel.

Sur les quatre sites que la mesure classe en coquille vide, moins de 100 mots servis au navigateur, l'écart change d'ordre de grandeur :

  • app.diagrams.net : 66 mots servis, 1 462 après exécution du JavaScript
  • excalidraw.com : 3 mots servis, 86 après rendu
  • todomvc.com, la démo React : 15 mots servis, 116 après rendu
  • squoosh.app : 68 mots servis, 69 après rendu

Aucune des quatre ne sert plus de 70 mots. Quatre cas, c'est trop peu pour une médiane de facteur de gain : le fichier de données met volontairement ce champ à null en dessous de cinq mesures valides, et on cite donc les cas un par un, pas une moyenne.

Une précaution sur ces médianes, facile à rater et pourtant décisive. La médiane des mots servis et la médiane des mots après rendu ne portent pas sur le même sous-ensemble de sites : tous n'ont pas de rendu valide. Leur quotient ne veut donc rien dire. Le seul gain de rendu qui tienne se calcule site par site, puis se médianise par classe, et c'est ce 1,13.

Ce que ce relevé établit, et il faut être précis : le HTML du premier fetch est tout ce qu'un fetch délivre. Ce qu'il n'établit pas : ce que GPTBot ou ClaudeBot font de ce HTML ensuite. On a mesuré des réponses HTTP, pas le comportement d'un crawler. Que les quatre User-Agent reçoivent le même HTML prouve que le serveur ne les distingue pas, et strictement rien d'autre.

Le point gênant, parce qu'il nous concerne : vydera.com passe de 1 635 mots servis à 2 039 après rendu, soit un facteur de 1,25, au-dessus de la médiane de 1,13 de sa propre classe. digidop.fr, bâti sur la même pile, reste à 1,03. La cause n'a pas été mesurée, et on ne la devinera pas ici.

Trois sites du panel résistent au rendu : photopea.com et swile.co ne gagnent aucun mot, squoosh.app en gagne exactement un. Là non plus la cause n'a pas été établie, et leur facteur voisin de 1,00 est donc un plancher, pas une mesure.

La pile technique ne prédit pas ce qui est servi

Le panel avait été classé à l'avance en trois familles : 10 sites attendus en HTML servi, du Webflow, du WordPress et de la presse, 10 sites en rendu serveur puis hydratation, du Next.js, du Nuxt et assimilés, et 7 applications attendues en rendu client. La mesure ne confirme que la première.

  • HTML servi : 10 sur 10. Prédiction tenue, tous servent un HTML complet.
  • Rendu serveur puis hydratation : 7 des 8 sites mesurables. De 527 mots pour vercel.com à 2 929 pour malt.fr. Le huitième, doctolib.fr, n'en sert que 228 au navigateur.
  • Rendu client : 4 sur 7 seulement sont des coquilles vides. photopea.com sert 430 mots, caniuse.com 424, regex101.com 229.

Le nom du framework ne dit donc pas ce que le serveur envoie. Sur notre panel, un site Next.js sert entre 527 et 2 929 mots selon la page et la configuration retenue. La question à poser à une pile headless n'est pas « est-ce que c'est du React », c'est « est-ce que le contenu principal est dans la réponse HTTP ». Elle se répond en deux lignes de terminal, pas en réunion d'architecture.

Le texte qui est dans la réponse mais pas dans le document

Un cas de figure passe sous les radars de la plupart des audits. Le blog français d'Ahrefs affiche 1 174 mots de texte visible dans son HTML servi, et embarque 137 366 mots de prose éditoriale française à l'intérieur de ses balises script. lesechos.fr, dans le même registre : 1 345 mots visibles contre 51 758 mots de prose dans les scripts.

Ce texte existe dans la réponse HTTP. Il n'est simplement pas dans le document. Ce qu'un moteur en fait dépend de la façon dont il lit la réponse, et le relevé ne tranche pas : ce qui est mesuré, c'est où le texte se trouve, pas qui le lit.

Deux précautions sur ce chiffre, parce qu'il est facile à gonfler. Deux comptes encadrent la réalité sans la donner. Le compte large ramasse du code et des dictionnaires de traduction d'interface : sur doctolib.fr il rend 160 663 mots dont zéro article. Le compte de prose, plus strict, ignore les chaînes en guillemets simples et les charges utiles encodées. Seul le second est cité ici.

Les h1 qui n'existent qu'après le rendu

Quatre des 25 sites mesurés ne présentent aucun h1 dans le HTML servi. Deux d'entre eux, doctolib.fr et la démo React de TodoMVC, en ont un une fois le JavaScript exécuté. Les deux autres, lesechos.fr et caniuse.com, n'en ont dans aucun des deux états.

Le h1 est le signal de structure le moins cher qui existe. S'il n'apparaît qu'après exécution, il existe pour qui rend la page, pas pour qui la récupère. Le test se fait en une ligne sur le fichier déjà téléchargé : grep -c -i '<h1' page.html. Même chose pour le titre, la meta description et les liens de navigation, qui se vérifient dans le HTML brut avant de se vérifier ailleurs.

robots.txt : une déclaration n'est pas une application

Sur les 21 fichiers robots.txt lisibles du panel :

  • 4 interdisent GPTBot, 4 interdisent ClaudeBot, 4 interdisent Google-Extended, 4 interdisent CCBot, 2 interdisent PerplexityBot
  • aucun n'interdit Googlebot
  • 15 des 21 ne nomment même pas GPTBot

Ne pas nommer un robot, c'est l'autoriser. Quinze sites sur vingt et un n'ont donc pris aucune décision sur le sujet, ce qui en est une. Si vous voulez trancher, la place de cette décision est le robots.txt, doublée le cas échéant d'un fichier llms.txt qui indique aux moteurs IA ce qu'il y a à lire chez vous.

Et la réciproque tient : lefigaro.fr et lesechos.fr interdisent GPTBot dans leur robots.txt et renvoient un 403 à Googlebot. Les deux dispositifs ne se pilotent pas au même endroit, ne se contrôlent pas ensemble, et se contredisent sans que personne ne le voie.

Ce que ce relevé ne prouve pas

  • Il ne prouve pas que GPTBot ou ClaudeBot n'exécutent pas le JavaScript. On mesure des réponses HTTP, pas des crawlers.
  • Il ne dit rien du second passage de rendu de Google ni de son délai. Il faudrait croiser les logs serveur et la Search Console, ce qui n'a pas été fait.
  • Il ne dit pas ce que voit le vrai Googlebot. Seul l'en-tête a été usurpé, depuis une adresse IP grand public.
  • Il ne couvre pas les pare-feux qui décident sur l'empreinte TLS ou HTTP/2 : seul le User-Agent a varié.
  • 27 sites choisis à la main, une seule IP, une seule géographie, un seul instant. Aucun pourcentage de ce relevé ne se généralise au web français.

Deux sites illustrent la différence entre « bloquant » et « non mesuré ». leboncoin.fr a renvoyé un 403 aux quatre User-Agent, navigateur compris : ce n'est pas un site bloquant, c'est un site non mesuré, et Chrome headless y a d'ailleurs obtenu 2 354 mots. reddit.com est sorti de l'échantillon pour la raison symétrique, son HTML servi se transformant en mur anti-bot une fois le JavaScript exécuté.

Ce qu'il faut faire, dans l'ordre

  1. Mesurez avant de croire quoi que ce soit. Deux lignes de terminal donnent le code HTTP, le poids et le compte de mots servi à chaque robot. Comptez trois minutes par page, sans rien débourser.
  2. Comparez d'abord les codes HTTP, pas les contenus. Sur notre panel, c'est là que se joue la totalité des écarts entre Googlebot et GPTBot.
  3. Comparez ensuite le HTML servi au DOM rendu. Au-delà d'un facteur de 1,5 sur le nombre de mots, votre contenu principal dépend du JavaScript.
  4. Vérifiez que votre h1, votre titre et vos liens de navigation sont dans le HTML servi. C'est le minimum structurel, et c'est ce qui coûte le moins cher à corriger.
  5. Regardez ce qui dort dans vos balises script. Un article entier peut être dans la réponse sans être dans le document.
  6. Décidez explicitement dans votre robots.txt quels robots IA vous acceptez, puis vérifiez que votre pare-feu dit la même chose. Une ligne de configuration contredit une politique sans prévenir.

Si la page concernée n'est pas indexée, le rendu n'est qu'une cause parmi sept, et rarement la bonne : on a passé les 168 URL de notre propre site à l'API d'inspection de Google pour les classer. Sur la partie balisée du sujet, voir les données structurées côté SEO et GEO. Et pour ce que les agents, eux, viennent chercher sur un site, WebMCP. Définitions : crawl et indexation.

  • Google exécute-t-il vraiment le JavaScript ?

    Google dispose d'un second passage de rendu qui exécute le JavaScript. Notre relevé ne mesure ni ce passage ni son délai, il mesure ce que le serveur envoie au premier fetch. Ce qu'il montre : sur les 19 sites servant déjà un HTML complet, l'exécution du JavaScript n'ajoute qu'un facteur médian de 1,13 sur le nombre de mots. Le HTML porte l'essentiel avant même que le rendu entre en jeu.

  • Les moteurs IA exécutent-ils le JavaScript ?

    Ce relevé ne permet pas de le dire, et il faut résister à la tentation de l'affirmer. Il mesure des réponses HTTP, pas le comportement d'un crawler. Ce qui est établi : le HTML du premier fetch est tout ce qu'un fetch délivre, et sur les quatre coquilles vides du panel il contient entre 3 et 68 mots.

  • Comment savoir si mon site dépend du JavaScript ?

    Récupérez la page avec curl, retirez scripts, styles et balises, comptez les mots. Récupérez la même page avec Chrome headless en mode --dump-dom, comptez les mots à nouveau. Le rapport entre les deux est votre facteur de rendu : au-delà de 1,5, votre contenu principal dépend du JavaScript. Sur les 19 sites au HTML complet de notre panel, la médiane est de 1,13.

  • Le rendu côté serveur est-il obligatoire pour le SEO ?

    Ce qui compte n'est pas la technique, c'est le résultat : le contenu principal doit être dans le HTML servi. Notre panel comptait 10 sites en rendu serveur puis hydratation, dont 8 mesurables : 7 servent un HTML complet, de 527 mots pour vercel.com à 2 929 pour malt.fr. Le huitième, doctolib.fr, n'en sert que 228. À l'inverse, les quatre coquilles vides du panel servent entre 3 et 68 mots. La question à se poser est « qu'y a-t-il dans ma réponse HTTP », pas « quel framework j'utilise ».

  • Faut-il interdire GPTBot dans son robots.txt ?

    Sur les 21 robots.txt lisibles de notre panel, 4 interdisent GPTBot, 4 interdisent ClaudeBot, aucun n'interdit Googlebot, et 15 ne nomment même pas GPTBot. Ne pas nommer un robot revient à l'autoriser. Le choix vous appartient, mais il doit être explicite, et surtout vérifié au pare-feu : deux sites de notre panel interdisent GPTBot dans leur robots.txt tout en renvoyant un 403 à Googlebot.

  • Peut-on servir un contenu différent aux robots IA ?

    Techniquement oui, et deux sites du panel le font. lemonde.fr sert 1,81 fois plus de mots aux robots qu'à un navigateur. doctolib.fr sert 80 892 octets à GPTBot et 1 640 429 octets à ClaudeBot au même instant, avec un contenu éditorial qui n'apparaît que dans le premier. Servir un contenu qui diverge selon l'identité déclarée entre dans la définition du cloaking chez Google. Le faire en connaissance de cause, ou pas du tout.


Thibaut Legrand
Thibaut Legrand
Co-fondateur - Vydera