Chaque page de ce blog transporte trois types de textes. Les deux premiers : celui que vous lisez, et le HTML qui le structure pour votre navigateur. Le troisième est invisible, coincé dans le <head> : un bloc application/ld+json qu'aucun humain n'ouvrira jamais.
Ce billet explique ce que ce troisième texte fabrique : ce que Google en fait encore en 2026, ce qu'il ne sert plus à rien d'y mettre (la FAQ, le HowTo, et pourquoi). Et la raison pour laquelle cette couche devient plus importante au moment précis où ses récompenses historiques disparaissent.
Borne posée d'entrée : on parle ici de la couche de balisage, pas du SEO éditorial ni de la performance. Et on ne promettra aucun chiffre côté agents. Personne ne mesure sérieusement aujourd'hui combien une IA vous cite grâce à votre balisage. C'est un pari raisonné, documenté comme tel.
Le troisième texte de la page
Le JSON-LD (JSON for Linking Data) est un format du W3C pour décrire des choses et leurs relations. Schema.org est le vocabulaire qu'on y verse : un dictionnaire de types (Article, Person, Organization, des centaines d'autres) maintenu depuis 2011 par Google, Microsoft, Yahoo et Yandex.
Concrètement, sur un billet de ce blog, ça ressemble à ça (extrait raccourci du graphe réel) :
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://lecodeestdanslepre.fr/#organization",
"name": "Lecodeestdanslepre"
},
{
"@type": "Person",
"@id": "https://lecodeestdanslepre.fr/a-propos#person",
"name": "Pierre",
"knowsAbout": ["PHP", "Symfony", "PostgreSQL", "Docker"]
},
{
"@type": "TechArticle",
"@id": "https://lecodeestdanslepre.fr/billets/mon-billet#article",
"headline": "Le titre du billet",
"author": { "@id": "https://lecodeestdanslepre.fr/a-propos#person" },
"about": [
{ "@type": "Thing", "name": "Symfony", "sameAs": "https://www.wikidata.org/wiki/Q1322933" }
]
}
]
}Trois mécanismes portent tout le reste. Le @graph : la page ne déclare pas un objet isolé mais un ensemble de nœuds. Les @id : chaque nœud a une adresse stable, et les nœuds se référencent entre eux (l'article pointe vers son auteur par @id au lieu de le dupliquer). Le sameAs : un nœud peut se déclarer identique à une entité externe, ici une entrée Wikidata.
Ce dernier point a l'air anecdotique. C'est lui qui va devenir central plus bas : Q1322933, c'est Symfony le framework, sans ambiguïté possible avec un genre musical ou un festival.
Ce que Google en fait encore
Historiquement, on balisait pour les rich results : les enrichissements visuels de la page de résultats. Étoiles d'avis, fil d'Ariane, recettes avec photo. Le contrat était simple : du balisage contre des pixels.
En 2026, ce contrat s'est réduit, mais il existe encore. Sur un blog technique, trois choses continuent de travailler :
Article/TechArticle: l'éligibilité aux blocs d'actualité et l'attribution correcte (titre, date, auteur) dans les résultats.BreadcrumbList: le fil d'Ariane affiché sous l'URL dans les résultats.- Le graphe entité :
Organization,Personet leurssameAsalimentent le knowledge graph. C'est la matière première de ce que Google appelle E-E-A-T : relier un contenu à un auteur identifiable, avec des sujets de prédilection (knowsAbout) et des profils vérifiables (GitHub, LinkedIn).
Le reste du bénéfice est indirect : un graphe propre aide les systèmes de Google à comprendre la page, même sans encart à la clé.
Ce qu'il ne faut plus baliser
C'est la partie que la doc de schema.org ne vous dira pas : le vocabulaire documente des centaines de types comme si tous avaient un débouché. La liste des enrichissements réellement affichés, elle, ne fait que rétrécir. Quatre cas concrets.
FAQPage. Depuis août 2023, Google n'affiche plus l'encart FAQ que pour les sites gouvernementaux et de santé faisant autorité. Pour un blog, ce balisage n'a plus aucun débouché visuel. Les pages de doc qui recommandent encore d'ajouter une FAQ balisée « pour le SEO » recyclent un conseil de 2021.
HowTo. Retiré dans la même annonce : d'abord réduit au desktop, puis abandonné. Un tutoriel reste un excellent contenu ; son balisage HowTo ne déclenche plus rien.
speakable. Pensé pour la lecture vocale, resté en bêta, jamais généralisé. Balisage sans consommateur.
Doubler les types. Publier un même billet en TechArticle et en BlogPosting « pour couvrir large » n'apporte rien et brouille le graphe. Un contenu, un type, le plus précis. Le lien avec le blog se fait par la relation (isPartOf vers un nœud Blog), pas par la multiplication des étiquettes.
Mention spéciale au sitelinks search box : Google l'a officiellement retiré fin 2024. Le balisage SearchAction associé ne produit donc plus d'encart. Ce blog le conserve pourtant. Ce n'est pas de la nostalgie : c'est le premier indice que le lectorat de cette couche est en train de changer.
Pourquoi les agents changent le calcul
Les AI Overviews sont arrivés en France cette année. ChatGPT, Perplexity et leurs cousins crawlent le web, reformulent, et citent leurs sources. Une part croissante des lectures de ce blog ne passe plus par un navigateur : elle passe par une machine qui lit pour quelqu'un d'autre.
Pour aller plus loin
AI Overviews arrive en France : faut-il vraiment optimiser ?
Or une machine qui lit une page fait face au même problème que Google en 2011. Le HTML dit « voici du texte », il ne dit ni « ceci est un article », ni « écrit par cette personne », ni « ce Symfony-là ». Le JSON-LD répond exactement à cette question, dans un format que la machine parse en une ligne, sans interpréter ni le CSS ni le DOM.
C'est ici que le sameAs vers Wikidata prend son poids. Pour un moteur de réponse, désambiguïser une entité est un problème statistique : il devine d'après le contexte. Un identifiant Wikidata transforme la devinette en lecture : Q1322933 ne désigne qu'une seule chose au monde. On appelle ça du GEO ou de l'AEO (Generative/Answer Engine Optimization), mais le principe tient en une phrase : donner aux machines des identifiants au lieu de leur laisser deviner des noms.
Et c'est pour ça que la mort des rich results ne signe pas la mort du balisage. Les encarts étaient la récompense visible d'une couche dont la fonction réelle, décrire le contenu aux machines, n'a jamais été aussi sollicitée. Le JSON-LD est le seul texte du site écrit dans la langue maternelle des machines. Au moment où les machines deviennent le premier lecteur, ce texte-là cesse d'être décoratif.
Ce que ça donne sur ce blog
La théorie s'arrête ici. Voici l'implémentation, telle qu'elle tourne en production.
Un seul script, un seul graphe. Chaque page émet un unique <script type="application/ld+json"> contenant un @graph avec un seul @context racine. Quatre nœuds globaux sont réémis sur toutes les pages avec des @id stables : Organization, Person, WebSite et Blog. Le nœud de page s'y raccroche, et le TechArticle d'un billet déclare isPartOf vers le nœud Blog.
Le type est de l'architecture, pas du contenu. Il n'y a aucun champ « type de schéma » dans l'admin. Un billet est un TechArticle, une page catégorie une CollectionPage, la page à-propos une ProfilePage qui enveloppe le nœud Person, la page contact une ContactPage. Tout est dérivé du modèle. Un choix qu'on referait : un menu déroulant d'options schema.org dans un CMS, c'est une invitation permanente à l'incohérence.
Chaque gabarit déclare son contenu. La home énumère ses billets dans une ItemList, l'index des billets pointe vers le nœud Blog (enrichi de la liste blogPost), chaque catégorie liste ses billets. Une machine peut reconstruire la carte du site sans crawler le HTML.
Les entités sont générées par IA, mais jamais sur parole. Les about et mentions d'un billet (les sujets qu'il traite, les technologies qu'il cite) sont proposés par Gemini à la demande, depuis l'éditeur, puis relus et acceptés un par un. Le garde-fou est strict : un dictionnaire de 26 identifiants Wikidata vérifiés à la main dans une classe est injecté dans le prompt. Tout identifiant proposé hors de ce dictionnaire est écarté avant persistance.
Sur le même sujet
Générer son SEO avec Symfony AI et Gemini
Un LLM invente volontiers des identifiants plausibles, et un sameAs faux est pire qu'aucun sameAs : il relie le contenu à la mauvaise entité, avec aplomb.
Les images aussi sont du graphe. Les cartes d'aperçu (1200×630) sont générées côté serveur avec Imagick et référencées en primaryImageOfPage, avec leurs métadonnées de licence (CC BY-SA, crédit, page de contact pour la réutilisation).
Le graphe est testé. Un test fonctionnel parcourt les gabarits du site et vérifie que chaque référence @id du graphe résout vers un nœud défini sur la page. Un graphe lié dont les liens pendent dans le vide, aucun validateur en ligne ne viendra vous le reprocher en continu ; un test, si.
Côté bibliothèques : spatie/schema-org fournit des builders PHP typés pour tout le vocabulaire (on écrit Schema::techArticle()->headline(...), l'autocomplétion fait le reste). Autour : symfony/ai porte les appels Gemini, symfony/object-mapper projette les suggestions IA vers les entités Doctrine, et symfony/json-path sert aux assertions des tests sur le graphe rendu.
La suite
Pendant quinze ans, on a balisé pour décorer une page de résultats. Les décorations s'éteignent une à une, et beaucoup en concluent que la couche entière est de la dette. C'est l'inverse qui est en train de se produire : la page de résultats perd de l'importance, et l'interface de lecture des machines en gagne. Le balisage change simplement de destinataire.
Ce blog pousse la logique un cran plus loin en explorant WebMCP, pour exposer des outils aux agents directement depuis les pages. Le graphe schema.org décrit ce que le site contient ; la suite, c'est décrire ce que le site sait faire. On en reparle dès que ça tourne.
Et vous, quand un agent lira vos pages à la place de vos lecteurs : qu'est-ce qu'il comprendra de qui écrit, et de quoi ?
Une coquille, une erreur dans ce billet ? Signale-la-moi.