GEO Next.js : se faire citer par ChatGPT et Perplexity
Publié le
Développeur React & Next.js freelance
Une part croissante des requêtes informationnelles ne passe plus par une page de résultats Google classique. Les moteurs génératifs (ChatGPT, Perplexity, Google AI Mode, Gemini) répondent directement et ne citent que quelques sources. Les estimations chiffrées varient selon les acteurs du secteur, mais toutes convergent sur une croissance rapide de cette part depuis 2024. C'est précisément l'enjeu du GEO (Generative Engine Optimization).
Le problème : un site bien classé sur Google n'est pas automatiquement cité par ces moteurs. Les critères de sélection diffèrent. La partie technique du GEO, celle qui relève du développeur, tient à quelques leviers concrets : rendu côté serveur, données structurées, métadonnées et un fichier llms.txt. Cet article les détaille pour une application Next.js.
Dans cet article :
- Ce qu'est le GEO et en quoi il diffère du SEO
- Pourquoi le rendu serveur conditionne la visibilité dans les moteurs IA
- Comment implémenter les données structurées (JSON-LD) avec l'App Router
- Comment servir un fichier
llms.txtdepuis Next.js - La structure de contenu qui favorise la citation
- Les erreurs à éviter
GEO et SEO : deux logiques distinctes
Définition
Le terme GEO vient d'un article de recherche de 2023 ("GEO: Generative Engine Optimization", Aggarwal et al.). Il désigne l'optimisation d'un contenu pour qu'il soit cité dans les réponses générées par les moteurs s'appuyant sur des modèles de langage, par opposition au référencement classique qui vise un classement dans une liste de liens.
La différence pratique tient à l'unité de visibilité. En SEO, l'objectif est qu'une page se classe. En GEO, l'objectif est qu'un passage précis soit extrait, cité et attribué à votre domaine dans une réponse synthétisée.
| Critère | SEO classique | GEO |
|---|---|---|
| Surface de réponse | Liste de liens bleus | Réponse synthétisée avec quelques sources citées |
| Unité optimisée | La page | Le passage extractible |
| Signal principal | Backlinks, intention, performances | Clarté, structure, autorité factuelle |
| Crawler | Googlebot, Bingbot | GPTBot, PerplexityBot, Google-Extended, ClaudeBot |
| Vérification | Search Console | Tester la requête directement dans chaque moteur |
Pourquoi les deux ne se recouvrent pas
Les analyses de citations relayées en 2026 montrent que le recouvrement entre les domaines cités par ChatGPT et ceux cités par Perplexity est faible : être cité par l'un ne garantit pas de l'être par l'autre. Chaque moteur a sa propre logique de sélection et sa propre source d'index (le moteur de recherche de ChatGPT s'appuie largement sur Bing, par exemple). Conséquence concrète : soumettre un sitemap à Bing Webmaster Tools, et pas seulement à Google Search Console, devient un prérequis pour apparaître dans les sources de ChatGPT.
Le SEO reste un préalable. Un contenu non indexable n'a aucune chance d'être cité. Le GEO ajoute une couche de lisibilité et de structure par-dessus.
Le rendu serveur conditionne la visibilité
C'est le point le plus structurant, et celui qui relève directement de l'architecture Next.js.
Le problème du rendu côté client
Les crawlers IA récupèrent le HTML d'une page, mais ne l'exécutent pas comme un navigateur. Une étude de Vercel menée sur son réseau montre que GPTBot (OpenAI), ClaudeBot (Anthropic) et PerplexityBot téléchargent les fichiers JavaScript mais ne les exécutent pas : ils ne lisent que le HTML de la réponse initiale. Googlebot reste à ce jour le seul crawler majeur dont le rendu JavaScript est mûr.
Conséquence : une application rendue entièrement côté client renvoie un HTML quasi vide, hydraté ensuite dans le navigateur. Pour ces crawlers, la page est vide.
"use client"
import { useEffect, useState } from "react"
export default function Produits() {
const [produits, setProduits] = useState([])
useEffect(() => {
fetch("/api/produits")
.then((r) => r.json())
.then(setProduits)
}, [])
return <ProductList produits={produits} />
}Le HTML servi ici ne contient aucun produit. Le contenu n'existe qu'après exécution du JavaScript et de la requête réseau. Un crawler IA qui ne rend pas le JavaScript ne voit rien à citer.
import { getProduits } from "@/data/produits"
export default async function Produits() {
const produits = await getProduits()
return <ProductList produits={produits} />
}Ici, le Server Component récupère les données pendant le rendu serveur. Le HTML renvoyé contient déjà la liste complète. Le contenu est lisible par n'importe quel crawler, JavaScript activé ou non.
C'est l'argument GEO le plus fort en faveur des Server Components : ils produisent du HTML complet par défaut. La généralisation abusive de "use client" reste l'un des anti-patterns React les plus coûteux, et il a désormais un impact direct sur la visibilité dans les moteurs IA.
Vérifier ce que voit un crawler
La méthode la plus fiable consiste à inspecter le HTML brut, sans exécution de JavaScript :
curl -s https://votre-site.fr/produits | grep -c "nom-de-produit-attendu"Si la commande renvoie 0, le contenu n'est pas dans le HTML initial. Les outils de test de données structurées de Google et le mode "vue source" du navigateur (et non l'inspecteur, qui montre le DOM hydraté) confirment ce diagnostic.
Implémenter les données structurées avec l'App Router
Les données structurées au format JSON-LD (schema.org) explicitent la nature du contenu : un article, sa date, son auteur, une FAQ, une organisation. Elles aident les moteurs à comprendre et à attribuer correctement la source.
Injecter du JSON-LD dans un Server Component
L'approche recommandée par la documentation Next.js consiste à rendre une balise <script> directement dans le composant serveur.
import { getArticle } from "@/data/articles"
export default async function ArticlePage({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
const article = await getArticle(slug)
const jsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: article.title,
description: article.description,
datePublished: article.date,
dateModified: article.updatedAt ?? article.date,
author: {
"@type": "Person",
name: article.author,
url: "https://votre-site.fr",
},
}
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
}}
/>
<ArticleContent article={article} />
</>
)
}Le JSON.stringify sérialise un objet typé, ce qui évite les erreurs de syntaxe d'un JSON écrit à la main. Le replace échappe le caractère inférieur par son équivalent Unicode : c'est la protection contre les injections XSS recommandée par la documentation officielle lorsque les données proviennent d'une source non maîtrisée.
Les types schema.org utiles
| Type | Usage | Bénéfice GEO |
|---|---|---|
Article / BlogPosting | Contenu éditorial | Date, auteur, sujet explicites |
FAQPage | Questions/réponses | Passages directement extractibles |
Organization / Person | Identité de l'entité | Attribution et autorité |
BreadcrumbList | Fil d'Ariane | Contexte de navigation |
Product / Offer | Fiches produit | Prix, disponibilité structurés |
Une page de FAQ avec un schéma FAQPage fournit des paires question/réponse que les moteurs peuvent reprendre quasiment telles quelles. C'est l'un des formats les plus efficaces pour le GEO.
Les métadonnées avec l'API Metadata
Au-delà du JSON-LD, l'API Metadata de Next.js génère les balises <title>, <meta> et Open Graph côté serveur.
import type { Metadata } from "next"
import { getArticle } from "@/data/articles"
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>
}): Promise<Metadata> {
const { slug } = await params
const article = await getArticle(slug)
return {
title: article.title,
description: article.description,
openGraph: {
title: article.title,
description: article.description,
type: "article",
publishedTime: article.date,
},
}
}Ces métadonnées sont présentes dans le HTML initial, donc lisibles par tous les crawlers. Sur les pages rendues dynamiquement, Next.js diffuse normalement les métadonnées en streaming, mais il détecte les robots connus (Bingbot et consorts) et leur sert les balises directement dans le <head>, justement pour rester lisible par les crawlers. La liste de ces robots est configurable via l'option htmlLimitedBots.
Servir un fichier llms.txt depuis Next.js
Ce qu'est llms.txt
llms.txt est un fichier Markdown placé à la racine du site (https://votre-site.fr/llms.txt). Il joue pour les modèles de langage un rôle analogue à celui de robots.txt pour les moteurs de recherche : il fournit un index lisible et organisé du contenu le plus important. La spécification définit une structure précise :
- un titre
H1(seule section obligatoire) ; - un bloc de citation (
>) résumant le projet ; - des sections
H2contenant des listes de liens au format[nom](url): description.
# Dimitri Dumont — Développeur React & Next.js freelance
> Articles techniques et services autour de React, Next.js et TypeScript.
## Articles
- [GEO Next.js](https://votre-site.fr/blog/geo-nextjs): rendre un site Next.js citable par les moteurs IA
- [Anti-patterns React 2026](https://votre-site.fr/blog/anti-patterns-react-2026): six erreurs courantes et leurs corrections
## Services
- [Audit de code](https://votre-site.fr/services/audit-code): diagnostic et plan de remédiationL'implémentation : fichier statique ou Route Handler
Pour un contenu fixe, le plus simple est un fichier dans public/ :
# Mon site
> Description du site
...Pour un contenu généré à partir des données (liste d'articles, par exemple), un Route Handler permet de produire le fichier dynamiquement et de le mettre en cache.
import { getAllArticles } from "@/data/articles"
export const dynamic = "force-static"
export async function GET() {
const articles = await getAllArticles()
const lignes = articles.map(
(a) => `- [${a.title}](https://votre-site.fr/blog/${a.slug}): ${a.description}`,
)
const contenu = [
"# Mon site",
"> Articles React, Next.js et TypeScript.",
"",
"## Articles",
...lignes,
].join("\n")
return new Response(contenu, {
headers: { "Content-Type": "text/plain; charset=utf-8" },
})
}Le force-static génère le fichier au build et le sert comme un actif statique. Il se régénère à chaque déploiement, ce qui suffit pour un index de contenu.
La structure de contenu qui favorise la citation
Au-delà de la technique, la forme du contenu influence sa probabilité d'extraction. Les études GEO et les analyses de citations convergent sur quelques constantes.
Répondre dès la première phrase
Les modèles extraient en priorité les phrases de définition placées en ouverture. Ouvrir chaque section importante par une réponse directe, plutôt que par une mise en contexte, augmente la probabilité d'extraction.
❌ « Avant de comprendre le GEO, il faut revenir sur l'histoire des moteurs. »
✅ « Le GEO désigne l'optimisation d'un contenu pour qu'il soit cité par les moteurs génératifs. »Privilégier les formats structurés
Plusieurs analyses de citations publiées en 2026 convergent : les pages comportant des tableaux et des listes structurées sont plus souvent reprises que les pages en prose seule. Les tableaux comparatifs, les listes d'étapes et les sections « En résumé » sont autant de blocs faciles à extraire.
Soigner l'autorité factuelle
Citer des sources vérifiables (documentation officielle, articles de recherche, données datées) renforce la fiabilité perçue par les moteurs. Les chiffres précis et attribués sont préférés aux affirmations vagues. Cet article applique lui-même ces principes : c'est le moyen le plus simple d'en vérifier l'effet.
Les erreurs à éviter
Chasser le GEO en négligeant le SEO de base. Sans indexation, sitemap et HTML accessible, aucun moteur génératif ne trouve le contenu à citer. Le GEO se construit par-dessus un référencement sain, pas à sa place.
Bloquer les crawlers IA par défaut. Vérifier que robots.txt ne bloque pas GPTBot, PerplexityBot, Google-Extended ou ClaudeBot si l'objectif est d'être cité. Le choix d'autoriser ou non ces robots est une décision à part entière (protection du contenu contre visibilité), mais elle doit être consciente.
Tout rendre côté client. C'est l'erreur la plus fréquente et la plus pénalisante. Un site en rendu client intégral est invisible pour la majorité des crawlers IA. Si chaque page commence par "use client", c'est un signal qu'une revue d'architecture est nécessaire.
Injecter du JSON-LD incohérent avec le contenu visible. Les données structurées doivent décrire fidèlement la page. Un schéma FAQPage sans FAQ visible, ou un Article daté différemment du contenu, dégrade la confiance et peut être ignoré.
Traiter llms.txt comme une solution miracle. C'est un complément à faible coût, pas un substitut aux fondamentaux. Le contenu, sa structure et son accessibilité priment.
FAQ
Quelle différence entre SEO et GEO ?
Le SEO vise un classement dans une liste de liens ; le GEO vise la citation d'un passage dans une réponse synthétisée. Les deux partagent des fondamentaux (contenu de qualité, indexabilité) mais diffèrent sur l'unité optimisée et les crawlers concernés. Le GEO se construit par-dessus un SEO sain, il ne le remplace pas.
Faut-il un fichier llms.txt pour être cité par les IA ?
Non, ce n'est pas obligatoire. Aucun grand moteur n'a confirmé l'utiliser comme signal en 2026. C'est une bonne pratique à faible coût qui peut aider, mais le rendu serveur, les données structurées et la qualité du contenu ont un impact bien plus direct. À implémenter une fois les fondamentaux en place.
Mon application Next.js en rendu client peut-elle être citée ?
Difficilement. Les principaux crawlers IA (GPTBot, ClaudeBot, PerplexityBot) n'exécutent pas le JavaScript et ne voient qu'un HTML vide. La migration des routes critiques vers des Server Components, qui produisent du HTML complet côté serveur, est le levier le plus efficace. Vérifiez avec curl ce que reçoit réellement un crawler.
Le GEO impacte-t-il les performances du site ?
L'impact est neutre, voire positif. Les techniques GEO (rendu serveur, HTML complet, données structurées) recoupent les bonnes pratiques de performance et de SEO. Le rendu serveur améliore le LCP, et le JSON-LD ajoute un poids négligeable au HTML.
Comment vérifier si mon site est cité par ChatGPT ou Perplexity ?
Tester directement les requêtes cibles dans chaque moteur. Il n'existe pas encore d'équivalent à Search Console pour les moteurs génératifs. Poser les questions auxquelles votre contenu répond, observer les sources citées, et vérifier l'indexation Bing (pour ChatGPT) via Bing Webmaster Tools.
Conclusion
Le GEO ne demande pas de réécrire un site, mais d'appliquer rigoureusement des fondamentaux que Next.js facilite déjà : rendu serveur par défaut, métadonnées générées côté serveur, données structurées explicites. La partie technique du GEO recoupe largement les bonnes pratiques de performance et d'accessibilité.
Points clés
- Le GEO complète le SEO : il optimise l'extraction et la citation d'un passage, pas seulement le classement d'une page
- Le rendu serveur est le prérequis le plus important : sans HTML complet, les crawlers IA ne voient rien
- Les données structurées (JSON-LD) explicitent le sens et facilitent l'attribution
llms.txtest un complément utile et peu coûteux, pas une garantie- La structure du contenu compte : réponse directe en ouverture, tableaux, listes, sources vérifiables
Checklist
- Vérifier le HTML brut avec
curl: le contenu est-il présent sans JavaScript ? - Migrer les routes critiques vers des Server Components
- Ajouter du JSON-LD (
Article,FAQPage,Organization) cohérent avec le contenu - Générer les métadonnées via l'API Metadata
- Publier un
llms.txtà la racine - Soumettre un sitemap à Bing Webmaster Tools, pas seulement à Google
- Structurer chaque page : réponse directe, tableaux, listes

À propos de l'auteur
Je suis Dimitri Dumont, développeur freelance spécialisé React & Next.js depuis plus de 8 ans. J'ai accompagné 22 startups et réalisé 44 missions avec une note de 5/5. Je partage ici les pratiques que j'utilise en mission. En savoir plus →
Une question sur cet article ?
Cet article vous a été utile ?
Je peux vous accompagner sur votre projet React & Next.js.
Discutons de votre projet →