Nesting Balisage de données structurées (@id and @graph)

Le deep-dive on connecting JSON-LD entities avec @id et @graph — stable identifiers, le deux canonical node patterns (Site web→Article→Author, Produit→Offer→Organization), le three mistakes que break le graph, et le honest limites de ce que Google's docs confirmer.

Première publication : 2 juil. 2026 · Dernière mise à jour : 3 août 2026 · Avancé

«Nesting connects your JSON-LD entities instead of dumping them as disconnected blocks. @id is a stable, unique URI (usually a canonical URL plus a #fragment) that names an entity so other entities can reference it — an Article's author pointing at a Person node, a Product's Offer pointing at an Organization/seller — rather than re-declaring the full entity everywhere. @graph is a keyword that bundles those connected entities into one script block. Google's docs confirm both nesting and individual items work, and that @id is how you tell Google two items are linked, but they never confirm whether @id resolves across pages — so the safe default is consistent @id values plus the complete entity graph on every page that needs it. Two patterns to learn: WebSite → WebPage → Article → Author for publishing, Product → Offer → Organization for ecommerce. Three ways it breaks or costs you: inconsistent/non-unique @id values, orphaned references (an @id cited but never declared — a semantic gap, not invalid JSON-LD), and duplicating a full entity's declaration everywhere instead of referencing it (a maintenance trap; same-entity repeats merge rather than literally break, but a genuinely conflicting reused @id is a real break). It's an entity-understanding tool, not a ranking or rich-result lever by itself.» _(Traduction)_ (Résumé en français du champ tldr : le texte source est conservé pour relecture francophone.)

TL;DR — Nesting connects JSON-LD entities via @id (a stable, unique URI — généralement une URL canonique plus a #fragment) donc vous référence an entity au lieu de re-declaring il, et @graph (a mot-clé bundling connected entities dans un script bloquer). Google’s docs confirmer les deux nesting et individual éléments fonctionner, et que vous utiliser @id à lien connexe éléments — mais ils jamais confirmer si @id resolves à travers pages, donc le sûr par défaut est consistent @id valeurs plus le complet entity graph on chaque page que nécessite il. Apprendre deux patterns: WebSite → WebPage → Article → Author (publishing) et Product → Offer → Organization/seller (ecommerce). Three échec modes à watch pour: inconsistent/non-unique @id valeurs, orphaned références (an @id cited mais jamais declared — semantically incomplete, pas invalide JSON-LD), et duplicate complet declarations de le même entity (a maintenance trap; même-entity repeats merge sous JSON-LD’s node règles, mais reusing un @id pour genuinely différent entities est a réel conflict). c’est an entity-understanding outil — disambiguation et de-duplication — pas a classement or rich-résultat lever par itself.

Preuve à l’appui de cette affirmation JSON-LD supports connected nodes via nesting or @id references, allowing multiple related entities to form one graph. Portée : JSON-LD graph model. Niveau de confiance : élevé · Vérifié : W3C JSON-LD 1.1 Preuve à l’appui de cette affirmation Google requires structured data to represent visible page content and follow each feature's specific nesting and property guidelines; extra valid nodes do not create eligibility by themselves. Portée : Current Google structured-data general guidelines. Niveau de confiance : élevé · Vérifié : Google Search Central: Structured data general guidelines

Scope: ce is the deep-dive, pas the intro

Ce article assumes vous déjà know ce que JSON-LD est et pourquoi c’est le recommended format — le balisage de données structurées page covers que, et il introduces @id/@graph En un coup d’œil. Ce page est le deferred deep-dive: le réel mechanics, le standard node patterns, et le spécifique mistakes que quietly break le graph. Si vous vouloir le format basics or où à placer le <script> bloquer, JSON-LD est le sibling pour que.

@id — a stable identifier, pas a fetchable URL

@id assigns a unique URI to a JSON-LD entity so autre entities peut point at it by référence. The convention — consistent à travers every credible source I’ve vérifié — is an absolute URL canonique plus a descriptive fragment:

"@id": "https://example.com/#organization"
"@id": "https://example.com/#website"
"@id": "https://example.com/team/jane-doe/#person"

Two choses personnes obtenir incorrect ici:

  • Il ne fait pas ont à resolve. Per le JSON-LD spec, @id’s job est node identification — a unique, stable “name” pour an entity — pas fetchability. En utilisant a fragment on votre propre domain est standard pratique et ne fait pas exiger que fragment URL à independently charger as une page. Sitebulb’s node-identifiers guide frames il bien: a node identifier est “a unique ‘nom’ pour an entity, qui est publicly accessible et peut être looked up or lié à.”
  • @id n’est pas url. ils sont différent properties doing différent jobs. @id identifies le node dans le graph; url décrit a réel, fetchable page à propos de le entity. An Organization peut (et souvent devrait) ont les deux — an @id de https://example.com/#organization et a url de https://example.com/.

Et @id valeurs sont case-sensitive — #Organization et #organization sont deux différent entities. Pick a convention et jamais drift depuis il.

@graph — bundling connected entities into un block

@graph est a JSON-LD mot-clé que lets vous put plusieurs top-level entities dans un array à l’intérieur a unique <script type="application/ld+json"> bloquer, avec entities cross-referencing chaque autre par @id:

{
  "@context": "https://schema.org",
  "@graph": [
    { "@type": "Organization", "@id": "https://example.com/#organization", "...": "..." },
    { "@type": "WebSite", "@id": "https://example.com/#website", "...": "..." },
    { "@type": "WebPage", "@id": "https://example.com/post/#webpage", "...": "..." }
  ]
}

@graph est a container, pas a requirement. Vous pouvez absolutely utiliser séparé <script> bloque pour individual éléments — Google’s docs confirmer les deux approaches fonctionner. Le raison à reach pour @graph est maintainability: une fois vous ont three or plus cross-referencing entities, vous écrire @context une fois à le top au lieu de repeating il dans chaque bloquer, et tout que références tout sinon lives dans un placer. Ce est le modèle Yoast utilise dans production — son schema architecture docs expliquer que a shared graph lets les “éviter having à duplicate or repeat shared properties, et à reduce le amount de code/processing/overhead requis.”

Pourquoi nest at tout — and ce que Google en réalité dit

Declare chaque entity une fois et connecter le graph avec stable `@id` références au lieu de repeating complet bloque.

Un Organization identified as hash organization est referenced as publisher par le Site web et Article. Le WebPage belongs à le Site web et est connected à le Article. Chaque entity est declared une fois, et le même stable à-id string est reused pour chaque référence.

«Google documents two structural options and confirms it understands both. From the General Structured Data Guidelines: “Google Search understands multiple items on a page, whether you nest the items or specify each item individually.” It defines them plainly — nesting is “when there is one main item, and additional items are grouped under the main item”, and individual items is “when each item is a separate block on the same page.” » (Traduction) (Résumé en français de la section cinquante, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«The one paragraph that’s the closest thing to an official rationale for @id is this: “If there are items that are more helpful when they are linked together (for example, a recipe and a video), use @id in both the recipe and the video items to specify that the video is about the recipe on the page. If you didn’t link the items together, Google Search may not know that it can show the video as a Recipe rich result.” That’s the mechanism in Google’s own words — @id is how you tell Google two items belong together. » (Traduction) (Résumé en français de la section cinquante et un, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Worth an honest remarque: Google’s docs state ce principle dans prose mais ne pas ship a worked @graph+@id code sample demonstrating il — leur code exemples montrer a nested Recipe et deux individual top-level éléments, aucun de qui en réalité cross-references par @id. Le exemples ci-dessous fill que gap.

Ce connects directement à schema’s deux jobs (le framing depuis le balisage de données structurées page): nesting bien est squarely an entity-understanding déplacer — disambiguation et avoiding contradictory/duplicated données — pas a rich-résultat trigger on son propre. Linking votre Article cleanly à son Author ne fait pas unlock a nouveau SERP fonctionnalité; il simplement rend le relationships unambiguous.

Modèle 1 — Site web → WebPage → Article → Author

Le canonical publishing modèle. Un Organization (le publisher), un WebSite, alors per-page a WebPage et le Article on il, avec author et publisher resolved par @id au lieu de re-declared:

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Example Media",
      "url": "https://example.com/",
      "logo": "https://example.com/logo.png",
      "sameAs": [
        "https://www.linkedin.com/company/example-media/",
        "https://en.wikipedia.org/wiki/Example_Media"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com/",
      "name": "Example Media",
      "publisher": { "@id": "https://example.com/#organization" }
    },
    {
      "@type": "WebPage",
      "@id": "https://example.com/nesting-schema/#webpage",
      "url": "https://example.com/nesting-schema/",
      "name": "Nesting Schema Markup",
      "isPartOf": { "@id": "https://example.com/#website" }
    },
    {
      "@type": "Person",
      "@id": "https://example.com/team/jane-doe/#person",
      "name": "Jane Doe",
      "url": "https://example.com/team/jane-doe/",
      "sameAs": ["https://www.linkedin.com/in/jane-doe/"]
    },
    {
      "@type": "Article",
      "@id": "https://example.com/nesting-schema/#article",
      "mainEntityOfPage": { "@id": "https://example.com/nesting-schema/#webpage" },
      "headline": "Nesting Schema Markup",
      "author": { "@id": "https://example.com/team/jane-doe/#person" },
      "publisher": { "@id": "https://example.com/#organization" }
    }
  ]
}

Remarque qu’est-ce que happening: author et publisher sont un-line références. Le Person et Organization sont declared une fois chaque. Le Article hangs off le WebPage (mainEntityOfPage), qui est isPartOf le WebSite, qui est publisher-ed par le Organization. c’est a connected graph, pas five islands.

Modèle 2 — Produit → Offer → Organization (seller)

Le ecommerce equivalent, et où nesting earns son garder à scale: au lieu de re-declaring votre merchant Organization on chaque un de thousands de produit pages, declare il une fois et référence il as le seller:

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://shop.example.com/#organization",
      "name": "Example Shop",
      "url": "https://shop.example.com/",
      "logo": "https://shop.example.com/logo.png"
    },
    {
      "@type": "Product",
      "@id": "https://shop.example.com/widget/#product",
      "name": "Deluxe Widget",
      "sku": "WIDGET-001",
      "brand": { "@type": "Brand", "name": "Example" },
      "offers": {
        "@type": "Offer",
        "price": "29.99",
        "priceCurrency": "USD",
        "availability": "https://schema.org/InStock",
        "seller": { "@id": "https://shop.example.com/#organization" }
      }
    }
  ]
}

Le Offer’s seller points à le shared Organization node. Même seller entity, un declaration, referenced depuis chaque produit. (Pour very grand variant sets, le même shared-@id idea extends à a ProductGroup avec variant Products — c’est a specialization de ce modèle, pas a différent mechanism.)

The three mistakes que break the graph

Ce is the practical heart of an audit. Quand nesting “doesn’t work,” it’s almost toujours un of ces three.

1. Inconsistent or non-unique @id valeurs

Le même entity donné différent @id strings à travers pages (or à travers a replatform/migration), donc moteur de recherches et validators voir les as unrelated entities au lieu de un. Or le opposite — reusing un @id pour deux genuinely différent entities. Le corriger est a strict, documented convention (e.g. {base-url}/#organization, {page-url}/#webpage, {profile-url}/#person) applied mechanically. Cas counts; #author ≠ #Author.

2. Orphaned références

An @id est referenced mais jamais declared. Vous écrire "author": {"@id": "https://example.com/#person-jane"}, mais aucun node anywhere dans le testé document en réalité declares que @id avec a @type et properties. Worth étant precise ici: a bare {"@id": "..."} object — ce que le JSON-LD spec calls a node référence (“a node object utilisé à référence a node having seulement le @id clé”) — est valide JSON-LD syntax on son propre; il n’est pas a parse erreur. Le problème est semantic et consumer-spécifique: le prévu connection — “ce Article’s author est ce Person” — jamais resolves à n’importe quoi utile, donc quelconque fonctionnalité or lecteur que nécessaire le author’s réel nom, URL, or sameAs données comes up vide. Ce est le sneaky un: validators souvent encore parse chaque declared élément sans erroring, donc rien screams à vous. Vous ship an incomplete graph et jamais notice. Momentic’s @id guide catalogs ce as un de le la plupart courant real-world nesting échecs.

3. Duplicate complet declarations of the même entity

Le opposite de orphaning: re-declaring le complet Organization/Person object inline on chaque page au lieu de referencing il une fois. Deux différent choses peut se produire ici, et c’est worth telling les apart:

  • Repeated declarations de le genuinely même entity. Per le JSON-LD spec, “le properties de a node dans a graph peut être spread parmi différent node objects dans a document. Quand que se produit, le keys de le différent node objects besoin à être merged à créer le properties de le résultating node.” Donc repeating le même @id avec le même (or compatible) données n’est pas a parse échec — processors merge il. Que ne fait pas faire il a bon idea: c’est encore ce que nesting exists à empêcher, et il bloats markup et crée a maintenance trap — mettre à jour votre adresse or logo dans un template, forget le autre forty, et le entity maintenant contradicts itself à travers le site. Les deux Ahrefs’ schema coverage et Schema App independently faire le même “modifier un et forget le others” point.
  • Le même @id reused pour deux en réalité différent entities. Ce est le réel break: deux node objects share an identifier mais décrire conflicting choses (a différent nom, a différent logo, a différent @type). c’est a semantic conflict, pas a harmless merge — pick a distinct @id pour chaque genuinely séparé entity.

Declare une fois, référence everywhere — le maintenance cas pour doing donc holds soit façon, même though a même-entity repeat ne va pas technically break le graph le façon an orphaned référence or a genuinely conflicting @id va.

The unresolved question: fait @id resolve à travers pages?

Ici’s le honest limite que separates a réel réponse depuis le confident-mais-wrong version. Google’s documentation jamais explicitly states si @id références resolve à travers pages — e.g., a produit page’s Offer.seller pointing à an Organization node c’est declared seulement on le homepage. Aucun Recherche Google Central document utilise “cross-page” or “across pages” dans relation à @id.

«The one nearby signal points toward self-contained pages: Google recommends, for duplicate content, “placing the same structured data on all page duplicates, not just on the canonical page” — which implies structured data is evaluated per page, not fetched from elsewhere. And there’s no on-the-record statement from a named Google or Bing rep (Mueller, Illyes, Splitt) specifically resolving the cross-page @id question that I could verify. Bing, for its part, has JSON-LD validation in Webmaster Tools but no published @id/@graph-specific guidance at all — a genuine documentation gap, not a position I’m going to invent for them. » (Traduction) (Résumé en français de la section soixante-quatorze, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Donc, as de July 2026, treat “Google suit @id liens dans pages” as an industry inference, pas a confirmed behavior. Le sûr par défaut — qui Yoast, Momentic, et Schema App tout converge on independently — est: garder @id valeurs consistent pour le même entity everywhere, mais encore sortie le complet entity graph on chaque page que nécessite il. ne pas assume Google va récupérer a referenced entity depuis a différent URL. Yoast’s production choice est exactly ce: il emits le complet graph on chaque page plutôt que relying on cross-page resolution.

Comment valider nested schema

Two outils:

  • Résultats enrichis Tester — dans practitioner testing as de July 2026, il parses @graph arrays et resolves @id références dans le testé document: quand entity A références B par @id et B est declared dans le même graph, ils montrer as connected; quand le referenced @id est jamais declared dans le testé markup, le outil encore parses le declared éléments individually sans erroring, mais ne peut pas montrer le connection. Google ne fait pas document ce UI behavior explicitly anywhere Je pourrait trouver, donc treat il as observed, reproducible outil behavior plutôt que an official specification — et re-vérifier il si le outil’s UI changements. Que behavior est exactly pourquoi orphaned références slip via — aucun erreur, simplement a manquant lien.
  • Balisage de données structurées Validator — schema.org’s propre vocabulary validator, moins opinionated à propos de Google’s pris en charge rich-résultat types.

Tester le rendu page, pas simplement votre template source — si JSON-LD est injected via JavaScript, confirmer c’est en réalité présent. Google documents reading JSON-LD c’est dynamically injected par JavaScript, mais c’est spécifique à Google — JavaScript-execution behavior varies par robot d’exploration et produit, et il y a aucun blanket règle que chaque AI robot d’exploration renders JS le même façon (or à tout). Shipping JSON-LD dans le initial HTML plutôt que assuming il’ll être executed est le conservative choice — c’est a schema-markup-pour-AI concern.

Myths worth killing

  • “@id nécessite à être a real, actif, fetchable URL.” Aucun — par convention c’est a URL canonique plus a fragment, mais son function est identification, pas fetchability. Le fragment ne fait pas besoin à resolve à son propre page.
  • “Même @id on différent pages auto-merges ceux entities dans Google’s indexer, comme a balise canonical consolidates pages.” Pas confirmed par quelconque Google doc. Consistent @id est bon hygiene, pas a proven cross-page consolidation mechanism.
  • “Vous doit utiliser @graph; séparé script bloque sont wrong.” Faux. Google understands les deux. @graph est a maintainability choice.
  • “More nesting always improves entity understanding.” Seulement si le entities sont genuinely connexe. Nesting unrelated éléments (Schema App’s exemple: an unrelated Event sous a Recipe) ne fait pas aider et peut muddy signaux.
  • “@id/@graph structure est a classement or rich-résultat factor.” Aucun. Son valeur est disambiguation et reduced duplication — consistent avec schema pas étant a classement factor à tout.
  • “An undeclared @id est harmless; moteurs simplement ignore il.” c’est le orphaned-reference échec — le prévu connection silently ne fait pas formulaire, et outils souvent ne pas erreur, donc vous ship il unnoticed.

Où ce sits

Ce est le comment-à couche sous le données structurées hub, a deeper sibling de balisage de données structurées (qui introduces @id/@graph) et JSON-LD (le format). Il leans on le même entity-understanding thinking as entities et balisage de données structurées pour AI — a well-built graph est entity infrastructure, si le consumer est Google’s Knowledge Graph or an LLM. Le entier sub-cluster lives à l’intérieur sur la page SEO.

Ajouter une note d’expert

Épingler une citation d’expert

Nouvelle personne ? Créez son profil non revendiqué à /admin/experts/ → Épingler une citation d’expert d’abord.