Nesting Schema Markup (@id and @graph)
The deep-dive on connecting JSON-LD entities with @id and @graph — stable identifiers, the two canonical node patterns (WebSite→Article→Author, Product→Offer→Organization), the three mistakes that break the graph, and the honest limits of what Google's docs confirm.
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.
Evidence for this claim JSON-LD supports connected nodes via nesting or @id references, allowing multiple related entities to form one graph. Scope: JSON-LD graph model. Confidence: high · Verified: W3C JSON-LD 1.1 Evidence for this claim 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. Scope: Current Google structured-data general guidelines. Confidence: high · Verified: Google Search Central: Structured data general guidelinesTL;DR — Nesting is how you connect your schema markupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. instead of leaving it as a pile of disconnected blocks.
@idis a unique name (usually your page URL plus a#tag) you give an entity — your organization, an author — so other entities can point at it instead of repeating all its details.@graphlets you put several connected entities in one code block. The payoff: declare your organization once, reference it everywhere, and don’t copy-paste the same block onto every page.
The problem nesting solves
Say your site has an Organization — a name, a logo, links to your social
profiles. And every blog post has an Article with an author and a publisher.
Without nesting, you end up writing out your full organization details — name,
logo, every social link — inside every single post’s markup. Change your logo,
and now you have to update it in forty places.
Nesting fixes that. You declare the organization once, give it a stable name, and everywhere else you just reference that name. This assumes you already know what schema markup and JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. are — if you don’t, start with the structured data hubStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. first, then come back here.
@id — a name you give an entity
@id is just a unique identifier for one entity. The convention is to use your
real page URL plus a fragment, like this:
{
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example Co",
"logo": "https://example.com/logo.png"
}That "@id": "https://example.com/#organization" is now the entity’s name.
Anywhere else you need to say “the publisher is Example Co,” you don’t rewrite all
of that — you just point at the name:
{
"@type": "Article",
"publisher": { "@id": "https://example.com/#organization" }
}One small but important thing: @id is an internal linkingAn internal link is a hyperlink from one page on a website to another page on the same website. Internal links help search engines discover your pages and pass ranking signals (PageRank and anchor-text context) between them. mechanism, not a page
you’re publishing. It doesn’t have to be a real, fetchable URL — using a fragment
on your own domain is standard, and that exact fragment doesn’t need to load as a
page. (That’s different from the url property, which does describe a real
page.)
@graph — putting connected entities together
@graph lets you list several entities in one code block instead of scattering
them across many. Rather than three separate <script> blocks, you write one:
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "Organization", "@id": "https://example.com/#organization", "name": "Example Co" },
{ "@type": "WebSite", "@id": "https://example.com/#website", "publisher": { "@id": "https://example.com/#organization" } }
]
}You write @context once at the top, and the entities inside reference each other
by @id. It’s tidier and easier to maintain once you have a few connected pieces.
The thing to get right
Two rules cover most of it:
- Be consistent. Use the same
@idstring for the same entity everywhere. If your organization is#organizationon one page and#orgon another, search engines can’t tell they’re the same thing. - Don’t point at nothing. If an
Article’s author references{"@id": "#author-jane"}, make sure#author-janeis actually declared somewhere with a@typeand details. A reference to an entity you never defined just fails silently.
And keep your expectations honest: nesting well helps search engines understand your entities and avoids duplicated data — it doesn’t, by itself, make you rank higher or unlock a rich result.
Want the full how-to — the two standard patterns with copy-paste examples, the three mistakes that break the graph, and what Google’s docs actually confirm (and leave silent)? Switch to the Advanced tab.
Audit a JSON-LD graph without inventing entities
Audit the JSON-LD below as a graph.
1. Inventory every declared node: @id, @type, and where it is declared.
2. Inventory every @id reference made by another node.
3. Flag exact orphan references, duplicate full declarations, case/fragment drift,
unstable-looking IDs, and relationships that point at the wrong entity type.
4. Distinguish a reference-only object ({"@id":"..."}) from a full declaration.
5. Do not assume an @id resolves across pages and do not invent missing facts.
6. Return (a) a findings table, (b) a minimal corrected graph using the existing
facts only, and (c) questions for facts that cannot be verified from the input.
JSON-LD:
[PASTE SCRIPT CONTENT]For a template comparison, provide two rendered graphs and ask the model to list
IDs that change unexpectedly between them. Stable entities such as the publisher
should retain the same case-sensitive @id; page-specific entities should remain
unique to their canonical page.
Find orphaned and duplicate IDs in rendered JSON-LD
Run this in DevTools Console. It parses every JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. block, walks arrays and
@graph, and separates full declarations from reference-only @id objects.
const documents = [...document.querySelectorAll('script[type="application/ld+json"]')]
.flatMap((script, scriptIndex) => {
try {
return [{ scriptIndex, value: JSON.parse(script.textContent) }];
} catch (error) {
console.warn(`Invalid JSON-LD in script ${scriptIndex + 1}`, error);
return [];
}
});
const declarations = new Map();
const references = [];
function walk(value, path, scriptIndex) {
if (Array.isArray(value)) {
value.forEach((item, i) => walk(item, `${path}[${i}]`, scriptIndex));
return;
}
if (!value || typeof value !== 'object') return;
if (typeof value['@id'] === 'string') {
const keys = Object.keys(value).filter((key) => key !== '@id');
if (keys.length) {
const rows = declarations.get(value['@id']) ?? [];
rows.push({ script: scriptIndex + 1, path, keys: keys.join(', ') });
declarations.set(value['@id'], rows);
} else {
references.push({ id: value['@id'], script: scriptIndex + 1, path });
}
}
Object.entries(value).forEach(([key, child]) =>
walk(child, `${path}.${key}`, scriptIndex));
}
documents.forEach(({ value, scriptIndex }) => walk(value, '$', scriptIndex));
console.table(references.filter(({ id }) => !declarations.has(id)));
console.table([...declarations.entries()]
.filter(([, rows]) => rows.length > 1)
.map(([id, rows]) => ({ id, declarations: rows.length, locations: rows })));An empty orphan table is useful, but it does not prove the graph is semantically correct. Review case-sensitive IDs, entity types, canonical URLsHow search engines pick one canonical URL among duplicates and consolidate signals onto it., and whether the complete graph needed by this page is actually present.
Evidence for this claim JSON-LD supports connected nodes via nesting or @id references, allowing multiple related entities to form one graph. Scope: JSON-LD graph model. Confidence: high · Verified: W3C JSON-LD 1.1 Evidence for this claim 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. Scope: Current Google structured-data general guidelines. Confidence: high · Verified: Google Search Central: Structured data general guidelinesTL;DR — Nesting connects JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. entities via
@id(a stable, unique URI — usually a canonical URLHow search engines pick one canonical URL among duplicates and consolidate signals onto it. plus a#fragment) so you reference an entity instead of re-declaring it, and@graph(a keyword bundling connected entities into one script block). Google’s docs confirm both nesting and individual items work, and that you use@idto link related items — but they never confirm whether@idresolves across pages, so the safe default is consistent@idvalues plus the complete entity graph on every page that needs it. Learn two patterns:WebSite → WebPage → Article → Author(publishing) andProduct → Offer → Organization/seller(ecommerce). Three failure modes to watch for: inconsistent/non-unique@idvalues, orphaned references (an@idcited but never declared — semantically incomplete, not invalid JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.), and duplicate full declarations of the same entity (a maintenance trap; same-entity repeats merge under JSON-LD’s node rules, but reusing one@idfor genuinely different entities is a real conflict). It’s an entity-understanding tool — disambiguation and de-duplication — not a ranking or rich-result lever by itself.
Scope: this is the deep-dive, not the intro
This article assumes you already know what JSON-LD is and why it’s the recommended
format — the schema markupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor.
page covers that, and it introduces @id/@graph at a glance. This page is the
deferred deep-dive: the actual mechanics, the standard node patterns, and the
specific mistakes that quietly break the graph. If you want the format basics or
where to place the <script> block, JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.
is the sibling for that.
@id — a stable identifier, not a fetchable URL
@id assigns a unique URI to a JSON-LD entity so other entities can point at it by
reference. The convention — consistent across every credible source I’ve checked —
is an absolute canonical URL plus a descriptive fragment:
"@id": "https://example.com/#organization"
"@id": "https://example.com/#website"
"@id": "https://example.com/team/jane-doe/#person"Two things people get wrong here:
- It doesn’t have to resolve. Per the JSON-LD spec,
@id’s job is node identification — a unique, stable “name” for an entity — not fetchability. Using a fragment on your own domain is standard practice and doesn’t require that fragment URL to independently load as a page. Sitebulb’s node-identifiers guide frames it well: a node identifier is “a unique ‘name’ for an entity, which is publicly accessible and can be looked up or linked to.” @idis noturl. They’re different properties doing different jobs.@ididentifies the node in the graph;urldescribes a real, fetchable page about the entity. AnOrganizationcan (and often should) have both — an@idofhttps://example.com/#organizationand aurlofhttps://example.com/.
And @id values are case-sensitive — #Organization and #organization are
two different entities. Pick a convention and never drift from it.
@graph — bundling connected entities into one block
@graph is a JSON-LD keyword that lets you put multiple top-level entities into one
array inside a single <script type="application/ld+json"> block, with entities
cross-referencing each other by @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 is a container, not a requirement. You can absolutely use separate
<script> blocks for individual items — Google’s docs confirm both approaches
work. The reason to reach for @graph is maintainability: once you have three or
more cross-referencing entities, you write @context once at the top instead of
repeating it in every block, and everything that references everything else lives in
one place. This is the pattern Yoast uses in production — its
schema architecture docs
explain that a shared graph lets them “avoid having to duplicate or repeat shared
properties, and to reduce the amount of code/processing/overhead required.”
Why nest at all — and what Google actually says
One Organization identified as hash organization is referenced as publisher by the WebSite and Article. The WebPage belongs to the WebSite and is connected to the Article. Each entity is declared once, and the same stable at-id string is reused for every reference.
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.”
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.
Worth an honest note: Google’s docs state this principle in prose but don’t ship a
worked @graph+@id code sample demonstrating it — their code examples show a
nested Recipe and two individual top-level items, neither of which actually
cross-references by @id. The examples below fill that gap.
This connects directly to schema’s two jobs (the framing from the
schema markupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. page):
nesting well is squarely an entity-understanding move — disambiguation and
avoiding contradictory/duplicated data — not a rich-result trigger on its own.
Linking your Article cleanly to its Author doesn’t unlock a new SERP featureSERP features are any element on a search results page beyond the classic ten blue links — featured snippets, People Also Ask, knowledge panels, sitelinks, image and video packs, AI Overviews, and structured-data-driven rich results. Google documents that losing rich-result eligibility doesn't affect ranking; their SEO relevance is CTR (they redistribute clicks). Some are unlocked by markup; most are purely algorithmic.; it
just makes the relationships unambiguous.
Pattern 1 — WebSite → WebPage → Article → Author
The canonical publishing pattern. One Organization (the publisher), one WebSite,
then per-page a WebPage and the Article on it, with author and publisher
resolved by @id instead of 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" }
}
]
}Note what’s happening: author and publisher are one-line references. The
Person and Organization are declared once each. The Article hangs off the
WebPage (mainEntityOfPage), which is isPartOf the WebSite, which is
publisher-ed by the Organization. That’s a connected graph, not five islands.
Pattern 2 — Product → Offer → Organization (seller)
The ecommerce equivalent, and where nesting earns its keep at scale: instead of
re-declaring your merchant Organization on every one of thousands of product
pages, declare it once and reference it as the 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" }
}
}
]
}The Offer’s seller points at the shared Organization node. Same seller
entity, one declaration, referenced from every product. (For very large
variant sets, the same shared-@id idea extends to a ProductGroup with variant
Products — that’s a specialization of this pattern, not a different mechanism.)
The three mistakes that break the graph
This is the practical heart of an audit. When nesting “doesn’t work,” it’s almost always one of these three.
1. Inconsistent or non-unique @id values
The same entity given different @id strings across pages (or across a
replatform/migration), so search engines and validators see them as unrelated
entities instead of one. Or the opposite — reusing one @id for two genuinely
different entities. The fix is a strict, documented convention (e.g.
{base-url}/#organization, {page-url}/#webpage, {profile-url}/#person) applied
mechanically. Case counts; #author ≠ #Author.
2. Orphaned references
An @id is referenced but never declared. You write
"author": {"@id": "https://example.com/#person-jane"}, but no node anywhere in the
tested document actually declares that @id with a @type and properties. Worth
being precise here: a bare {"@id": "..."} object — what the
JSON-LD spec calls a node reference (“a node
object used to reference a node having only the @id key”) — is valid JSON-LD syntax
on its own; it isn’t a parse error. The problem is semantic and consumer-specific:
the intended connection — “this Article’s author is that Person” — never resolves to
anything useful, so any feature or reader that needed the author’s actual name, URL,
or sameAs data comes up empty. This is the sneaky one: validators often still parse
each declared item without erroring, so nothing screams at you. You ship an
incomplete graph and never notice. Momentic’s
@id guide
catalogs this as one of the most common real-world nesting failures.
3. Duplicate full declarations of the same entity
The opposite of orphaning: re-declaring the complete Organization/Person object
inline on every page instead of referencing it once. Two different things can happen
here, and it’s worth telling them apart:
- Repeated declarations of the genuinely same entity. Per the
JSON-LD spec, “the properties of a
node in a graph may be spread among different node objects within a document. When
that happens, the keys of the different node objects need to be merged to create the
properties of the resulting node.” So repeating the same
@idwith the same (or compatible) data isn’t a parse failure — processors merge it. That doesn’t make it a good idea: it’s still what nesting exists to prevent, and it bloats markup and creates a maintenance trap — update your address or logo in one template, forget the other forty, and the entity now contradicts itself across the site. Both Ahrefs’ schema coverage and Schema App independently make the same “change one and forget the others” point. - The same
@idreused for two actually different entities. This is the real break: two node objects share an identifier but describe conflicting things (a different name, a different logo, a different@type). That’s a semantic conflict, not a harmless merge — pick a distinct@idfor each genuinely separate entity.
Declare once, reference everywhere — the maintenance case for doing so holds either
way, even though a same-entity repeat won’t technically break the graph the way an
orphaned reference or a genuinely conflicting @id will.
The unresolved question: does @id resolve across pages?
Here’s the honest limit that separates a real answer from the confident-but-wrong
version. Google’s documentation never explicitly states whether @id references
resolve across pages — e.g., a product page’s Offer.seller pointing at an
Organization node that’s declared only on the homepage. No Google Search Central
document uses “cross-page” or “across pages” in relation to @id.
The one nearby signal points toward self-contained pages: Google recommends, for
duplicate contentThe same or very similar primary content reachable at more than one URL. There's no general duplicate content penalty — the real costs are possible signal dilution, the wrong URL getting chosen, and less-efficient crawling., “placing the same structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. 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.
So, as of July 2026, treat “Google follows @id links across pages” as an
industry inference, not a confirmed behavior. The safe default — which Yoast, Momentic, and Schema App all
converge on independently — is: keep @id values consistent for the same entity
everywhere, but still output the complete entity graph on every page that needs it.
Don’t assume Google will fetch a referenced entity from a different URL. Yoast’s
production choice is exactly this: it emits the full graph on every page rather than
relying on cross-page resolution.
How to validate nested schema
Two tools:
- Rich Results Test — in
practitioner testing as of July 2026, it parses
@grapharrays and resolves@idreferences within the tested document: when entity A references B by@idand B is declared in the same graph, they show as connected; when the referenced@idis never declared in the tested markup, the tool still parses the declared items individually without erroring, but can’t show the connection. Google doesn’t document this UI behavior explicitly anywhere I could find, so treat it as observed, reproducible tool behavior rather than an official specification — and re-check it if the tool’s UI changes. That behavior is exactly why orphaned references slip through — no error, just a missing link. - Schema Markup Validator — schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor.’s own vocabulary validator, less opinionated about Google’s supported rich-result types.
Test the rendered page, not just your template source — if JSON-LD is injected via JavaScript, confirm it’s actually present. Google documents reading JSON-LD that’s dynamically injected by JavaScript, but that’s specific to Google — JavaScript-execution behavior varies by crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. and product, and there’s no blanket rule that every AI crawlerAI crawlers are bots from AI companies that fetch web pages to train language models, build AI-search indexes, or answer live user questions. They come in three categories, each with its own user-agent tokens and its own robots.txt controls. renders JS the same way (or at all). Shipping JSON-LD in the initial HTML rather than assuming it’ll be executed is the conservative choice — that’s a schema-markup-for-AISchema markup (structured data) is machine-readable code — usually JSON-LD — that labels what your content means using the schema.org vocabulary. For AI search it's infrastructure for entity disambiguation, not a direct citation lever: controlled studies found no meaningful uplift in AI citations from adding it. concern.
Myths worth killing
- “
@idneeds to be a real, live, fetchable URL.” No — by convention it’s a canonical URL plus a fragment, but its function is identification, not fetchability. The fragment doesn’t need to resolve to its own page. - “Same
@idon different pages auto-merges those entities in Google’s indexStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed., like a canonical tagA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content. consolidates pages.” Not confirmed by any Google doc. Consistent@idis good hygiene, not a proven cross-page consolidation mechanism. - “You must use
@graph; separate script blocks are wrong.” False. Google understands both.@graphis a maintainability choice. - “More nesting always improves entity understanding.” Only if the entities are
genuinely related. Nesting unrelated items (Schema App’s example: an unrelated
Eventunder aRecipe) doesn’t help and can muddy signals. - “
@id/@graphstructure is a ranking or rich-result factor.” No. Its value is disambiguation and reduced duplication — consistent with schema not being a ranking factor at all. - “An undeclared
@idis harmless; engines just ignore it.” That’s the orphaned-reference failure — the intended connection silently doesn’t form, and tools often don’t error, so you ship it unnoticed.
Where this sits
This is the how-to layer under the
structured data hubStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding., a deeper sibling of
schema markupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. (which
introduces @id/@graph) and JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.
(the format). It leans on the same entity-understanding thinking as
entities\"Entity & identity schema\" is a practitioner label — not an official Google or schema.org category, and not exhaustive of identity-capable schema.org types — for the three main types that declare who or what is behind a site: Organization, LocalBusiness, and Person. and
schema markup for AISchema markup (structured data) is machine-readable code — usually JSON-LD — that labels what your content means using the schema.org vocabulary. For AI search it's infrastructure for entity disambiguation, not a direct citation lever: controlled studies found no meaningful uplift in AI citations from adding it. — a well-built
graph is entity infrastructure, whether the consumer is Google’s Knowledge GraphThe Knowledge Graph is Google's database of entities — people, places, organizations, and things — and the factual relationships between them. It's separate from any single website's structured data: your schema markup is one of many possible inputs to the graph, not the graph itself. or
an LLM. The whole sub-cluster lives inside on-page SEO.
AI summary
A condensed take on the Advanced version:
- What it is. Nesting connects JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. entities instead of leaving disconnected
blocks.
@id= a stable, unique URI (usually canonical URLHow search engines pick one canonical URL among duplicates and consolidate signals onto it. +#fragment) that names an entity so others reference it by@idinstead of re-declaring it.@graph= a keyword bundling connected entities into one<script>block, cross-referencing via@id. @id≠url, and@idneedn’t resolve. Per the JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. spec,@idis node identification, not fetchability;urldescribes a real page.@idis case-sensitive.- Google’s confirmed position: it understands both nesting and individual
items, and you use
@idto tell Google two items are linked. It does not document cross-page@idresolution — treat “Google follows@idacross pages” as an industry inference, not confirmed. Nearest signal (“duplicate the same schema on all duplicate pagesThe same or very similar primary content reachable at more than one URL. There's no general duplicate content penalty — the real costs are possible signal dilution, the wrong URL getting chosen, and less-efficient crawling.”) points toward per-page/self-contained evaluation. - Two patterns:
WebSite → WebPage → Article → Author(publishing, withauthor/publisherby@id) andProduct → Offer → Organization/seller(ecommerce, one seller node referenced from every product). - Three failure modes: (1) inconsistent/non-unique
@idvalues; (2) orphaned references — an@idcited but never declared (semantically incomplete, not invalid JSON-LD; silent failure since validators often don’t error); (3) duplicate full declarations of the same entity (maintenance trap — same-entity repeats merge under JSON-LD’s node rules, but reusing one@idfor genuinely different entities is a real conflict). - Safe default: consistent
@ideverywhere plus the complete entity graph on every page that needs it — don’t rely on cross-page fetching. (Yoast, Momentic, Schema App all converge here.) - Validate with the Rich ResultsRich results (formerly 'rich snippets') are enhanced search listings — stars, images, prices, breadcrumbs, video thumbnails, and more — that Google and Bing build from structured data. They're a display feature, not a ranking factor, and eligibility never guarantees they'll show. Test (resolves
@idwithin the tested doc) and the schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. validator; test the rendered page. - Not a ranking or rich-result lever by itself — it’s entity understanding (disambiguation + de-duplication).
Official documentation
Primary-source documentation and specs.
- General Structured Data Guidelines — the one page where Google documents nesting vs. individual items and the
@id-linking principle (last updated July 10, 2026, confirmed live). Also the “duplicate the same structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. on all page duplicates” guidance. - Intro to How Structured Data Markup Works — format context and the completeness/accuracy rules.
- Rich Results Test — parses
@graphand resolves@idreferences within the tested document.
schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. / W3C
- W3C JSON-LD 1.1 Recommendation — the spec that defines
@id,@graph, node objects, and graph objects. - Schema Markup Validator — schema.org’s vocabulary validator (less tied to Google’s rich-result support list).
Bing / Microsoft
- Introducing JSON-LD Support in Bing Webmaster Tools — Bing’s Markup Validator supports JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.; note there is no published Bing guidance specific to
@id/@graphnesting mechanics.
Quotes from the source
On-the-record statements from Google. Each link is a deep link that jumps to the quoted passage.
Google — nesting vs. individual items
- “Google Search understands multiple items on a page, whether you nest the items or specify each item individually.” — Google Search Central, General Structured DataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. Guidelines. Jump to quote
Google — why @id exists (the linking principle)
- “…use
@idin 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 resultRecipe schema (schema.org/Recipe) marks up a cooking recipe's image, name, ratings, times, ingredients, and nutrition so the page can earn Google's recipe rich result — a visual card with star ratings and cook time, plus carousel and recipe-filter eligibility..” — same page. Jump to quote
Google — treat each page as self-contained (the nearest cross-page signal)
- “If you have duplicate pagesThe same or very similar primary content reachable at more than one URL. There's no general duplicate content penalty — the real costs are possible signal dilution, the wrong URL getting chosen, and less-efficient crawling. for the same content, we recommend placing the same structured data on all page duplicates, not just on the canonical page.” — same page. Jump to quote
On what’s not on the record
Google’s docs never explicitly confirm whether @id references resolve across
pages, and I couldn’t verify any on-the-record statement from a named Google or Bing
rep resolving that question. Where this article says “the safe default is consistent
@id plus the full graph per page,” that’s practitioner consensus (Yoast, Momentic,
Schema App converging independently), not a Google quote — I’ve labeled it as such
in the Advanced tab rather than dressing it up as official.
@id/@graph is not a ranking factor follows from Google’s
broader, repeatedly-stated position that structured data isn’t a direct ranking
signal — it is not a verbatim @id-specific quote. Nested schema — cheat sheet
@id vs. url vs. @graph
| Thing | What it is | Must it resolve to a page? |
|---|---|---|
@id | Unique identifier for an entity (node in the graph) | No — identification, not fetchability |
url | The entity’s real, fetchable page | Yes — it’s an actual URL |
@graph | Array bundling connected entities in one <script> block | N/A — it’s a container keyword |
@id conventions
- Absolute URL + descriptive fragment:
https://example.com/#organization. - Case-sensitive —
#Author≠#author. Pick one, never drift. - Same entity → same
@ideverywhere. Different entities → different@id. - Never a bare arbitrary string (
"id1").
The two patterns
| Pattern | Chain | Reference by @id |
|---|---|---|
| Publishing | WebSite → WebPage → Article | author → Person, publisher → Organization |
| Ecommerce | Product → Offer | seller → Organization |
Three things to watch for
| Mistake | What happens |
|---|---|
Inconsistent / non-unique @id | Same entity seen as two (or two entities collapsed into one) |
| Orphaned reference | @id cited but never declared → connection silently fails (valid JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal., but semantically incomplete; often no validator error) |
| Duplicate full declarations | Bloat + maintenance trap (same-entity repeats merge under JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.’s rules; reusing one @id for different entities is the real conflict) |
Fast facts
- Google confirms both nesting and individual items work;
@graphis optional. - Google does not document cross-page
@idresolution — assume per-page. - Safe default: consistent
@id+ complete graph on every page that needs it. - Not a ranking or rich-result lever — it’s entity understanding.
- Validate with the Rich ResultsRich results (formerly 'rich snippets') are enhanced search listings — stars, images, prices, breadcrumbs, video thumbnails, and more — that Google and Bing build from structured data. They're a display feature, not a ranking factor, and eligibility never guarantees they'll show. Test (resolves
@idin-document) and the schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. validator; test the rendered page.
Nesting anti-patterns
The specific ways nested schema goes wrong — and the fix for each.
Drifting @id conventions across templates
Your blog template emits #organization, your product template emits #org, and a
migrated section emits #company. Three strings, one real entity — now seen as
three. Fix: one documented convention, applied mechanically (ideally generated
from a single config, the way plugins do it).
Referencing an entity you never declared (orphan)
"author": {"@id": "#person-jane"} with no #person-jane node anywhere in the
document. The link resolves to nothing and the connection fails — and the Rich
Results Test usually won’t error, it just won’t show the connection. Fix: every
@id you reference must be declared once, in the tested markup, with a @type.
Re-declaring the full entity on every page
Copy-pasting the complete Organization (name, logo, every sameAs) inline into
every article and product. Works, but it’s a maintenance trap: change the logo once,
forget forty pages, and your entity now contradicts itself. Fix: declare once,
reference by @id everywhere else.
Nesting unrelated entities to “add more schema”
Bundling a Recipe, an unrelated Event, and a JobPosting under one graph
because “more markup is better.” Relatedness has to be real — co-location isn’t a
relationship. Fix: only connect entities that genuinely relate.
Assuming cross-page @id resolution
Declaring Organization only on the homepage and referencing it by @id from
product pages, expecting Google to fetch it. Google’s docs don’t confirm this works.
Fix: keep @id consistent, but include the complete entity on every page that
references it.
@id that’s really meant to be url (or vice versa)
Using @id where you need a fetchable page reference, or expecting url to link
graph nodes. They’re different jobs. Fix: @id for graph identity, url for the
real page; an entity can have both.
Case and trailing-slash inconsistency
https://example.com/#Org on one page, https://example.com/#org on another, or
.../post/#article vs .../post#article. All treated as distinct. Fix: normalize
exactly — case, slashes, protocol, host.
Worked examples
Copy-paste starting points for the two patterns and a correct reference.
Publishing: WebSite → WebPage → Article → Author
{
"@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/"]
},
{
"@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/post/#webpage",
"url": "https://example.com/post/",
"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/"
},
{
"@type": "Article",
"@id": "https://example.com/post/#article",
"mainEntityOfPage": { "@id": "https://example.com/post/#webpage" },
"headline": "Example headline",
"author": { "@id": "https://example.com/team/jane-doe/#person" },
"publisher": { "@id": "https://example.com/#organization" }
}
]
}Ecommerce: Product → Offer → Organization (seller)
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://shop.example.com/#organization",
"name": "Example Shop",
"url": "https://shop.example.com/"
},
{
"@type": "Product",
"@id": "https://shop.example.com/widget/#product",
"name": "Deluxe Widget",
"offers": {
"@type": "Offer",
"price": "29.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"seller": { "@id": "https://shop.example.com/#organization" }
}
}
]
}Correct reference vs. orphaned reference
Correct — the referenced node is declared in the same graph:
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "Person", "@id": "https://example.com/#jane", "name": "Jane Doe" },
{ "@type": "Article", "author": { "@id": "https://example.com/#jane" } }
]
}Broken (orphan) — #jane is referenced but never declared, so author resolves to
nothing:
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "Article", "author": { "@id": "https://example.com/#jane" } }
]
} Nested schema audit — checklist
A pass to confirm your graph is connected, consistent, and self-contained:
- One
@idconvention, documented and applied everywhere (e.g.{base}/#organization,{page}/#webpage,{profile}/#person). - Same entity → same
@idacross every page and template (no#orgvs.#organizationdrift; case and trailing slashesA trailing slash is the forward slash (/) at the end of a URL — example.com/page/ versus example.com/page. Except at the bare root domain, the two versions are different URLs to search engines, so you pick one format and enforce it. normalized). - No orphaned references — every
@idyou reference is actually declared, in the tested document, with a@typeand properties. - No duplicate full declarations — shared entities (
Organization,Person) are declared once and referenced by@id, not re-pasted inline. -
@idvs.urlused correctly —@ididentifies the node;urlpoints at the real page; an entity may have both. - Only genuinely related entities are connected — no unrelated items bundled just to add markup.
- Complete graph on every page that needs it — don’t rely on cross-page
@idresolution; include the referenced entities per page. - Validated in the Rich Results Test (connections show as linked) and the schema.org validator.
- Tested on the rendered page, not just template source (confirm JS-injected JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. is actually present; server-render for AI crawlersAI crawlers are bots from AI companies that fetch web pages to train language models, build AI-search indexes, or answer live user questions. They come in three categories, each with its own user-agent tokens and its own robots.txt controls.).
- Consistent markup across canonical + duplicate pagesThe same or very similar primary content reachable at more than one URL. There's no general duplicate content penalty — the real costs are possible signal dilution, the wrong URL getting chosen, and less-efficient crawling. — same structured data on all versions.
Test yourself: Nesting Schema Markup
Five quick questions on @id, @graph, and the mistakes that break a nested graph.
Pick an answer for each, then check.
Resources worth your time
My related writing
- Structured Data: What It Is and How to Use It — my Ahrefs guide to schema typesSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor., implementation methods, validation tools, and the
sameAsentity-disambiguation risk (the entity-understanding job@id/@graphserves). - The Beginner’s Guide to Technical SEO — where structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. sits in the bigger technical picture.
My speaking
- How Search Works (SlideShare) — my walkthrough of crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor., renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed., and ranking, for the context structured data feeds into. (My standing disclaimer applies: “This is my understanding of systems… not going to be 100% complete or accurate.”)
Official
- Google’s General Structured Data Guidelines — nesting vs. individual items and the
@id-linking principle. - W3C JSON-LD 1.1 Recommendation — the spec defining
@id,@graph, and node/graph objects. - Rich Results Test and the schema.org validator — the two tools for checking a nested graph.
From around the industry
- We Tracked 1,885 Pages Adding Schema. AI Citations Barely Moved. (Louise Linehan & Xibeijia Guan, Ahrefs) — an Ahrefs study on schema and AI citationsAn AI citation is the visible source link an AI answer engine shows next to its generated text — the clickable reference that credits the web page it used. A citation's presence is a separate thing from whether the cited page actually supports the statement, and from being retrieved (read behind the scenes) or merely mentioned (named without a link); citation is driven more by brand mentions and being retrievable than by traditional ranking., useful for calibrating expectations that clean markup, including nesting, is entity infrastructure rather than a citation cheat code.
- Node Identifiers: From Structured Data to Linked Data (Patrick Hathaway, Sitebulb) — the clearest “what a node identifier actually is” explainer, with a worked distinct-
@idexample and the case-sensitivity warning. - What is an @id in Structured Data? (Mark van Berkel, Schema App) — cites the JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. spec definition and the useful “entity home” framing (the page where an entity’s full definition lives).
- What is Nesting in Schema Markup? (Jasmine Drudge-Willson, Schema App) — nesting-for-hierarchy vs. -convenience, and why nesting unrelated entities is a mistake.
- Schema: Technology and approach (Yoast developer docs) — a real production
@grapharchitecture, its@idtemplate, and the candid “we output the full graph on every page rather than rely on cross-page resolution” choice. - Using @id in Schema.org Markup for SEO, LLMs & Knowledge Graphs (Tyler Einberger, Momentic) — a clean catalog of common
@idmistakes (orphaned references, unstable IDs, inconsistent values).
Nested Schema Markup (@id and @graph)
Nesting schema markup with @id and @graph is the practice of connecting multiple JSON-LD entities into one linked graph instead of declaring each in isolation. @id is a unique URI (usually a canonical URL plus a #fragment) that identifies an entity — a WebSite, Organization, or Person — so other entities can reference it by that URI instead of re-declaring all its properties. @graph is a JSON-LD keyword that bundles multiple top-level entities into one array inside a single <script type="application/ld+json"> block, cross-referencing each other via @id.
Related: Schema Markup, Structured Data, JSON-LD
Nested Schema Markup (@id and @graph)
Nesting schema markupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. with @id and @graph is the practice of connecting multiple JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. entities into a single, linked data graph instead of declaring each one in isolation.
@idis a unique URI — typically the entity’s canonical URLHow search engines pick one canonical URL among duplicates and consolidate signals onto it. plus a#fragment— that identifies a specific entity (aWebSite, anOrganization, aPerson) so other entities can reference it by that URI instead of re-declaring all of its properties inline. Per the JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. spec its job is node identification; it doesn’t have to resolve to a live, fetchable page. It’s distinct from the schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor.urlproperty, which does describe a fetchable page.@graphis a JSON-LD keyword that lets you bundle multiple top-level entities into one array inside a single<script type="application/ld+json">block, with entities cross-referencing each other via@id. It’s a maintainability choice, not a requirement — separate script blocks work too.
Together they turn a page’s structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. from a pile of disconnected blocks into a coherent graph. An Article’s author and publisher point at Person and Organization nodes defined once, rather than repeating the same name, logo, and sameAs data on every page. This is an entity-understanding mechanism — disambiguation and de-duplication — not a rich-result trigger by itself.
Related: Schema Markup, Structured Data, JSON-LD
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Updated Jul 21, 2026.
Editorial summary and recorded change details.Summary
Corrected a research misattribution: the 'We Tracked 1,885 Pages Adding Schema' AI-citations study is by Louise Linehan and Xibeijia Guan, not Patrick, so moved it out of 'My related writing' into 'From around the industry' with proper author attribution.
Change details
-
Removed the schema-ai-citations study from the 'My related writing' list, where it was wrongly credited as 'my Ahrefs study', and re-listed it under 'From around the industry' attributed to Louise Linehan & Xibeijia Guan (Ahrefs).
Full comparison unavailable — no prior snapshot was archived for this revision.
Updated Jul 18, 2026.
Editorial summary and recorded change details.Summary
Corrected an overstated claim that AI crawlers never execute JavaScript, split JSON-LD's node-merge behavior from genuine @id conflicts in the duplicate-declarations mistake, clarified that an orphaned @id reference is a semantic gap rather than invalid JSON-LD syntax, hedged the Rich Results Test behavior description as observed tool behavior rather than official documentation, and refreshed the sd-policies 'last updated' citation to its current date.
Change details
-
Replaced the categorical 'AI crawlers don't run JS at all' line with a hedged statement that JavaScript-execution behavior varies by crawler/product, live-verified against Google's structured-data intro docs.
-
Rewrote the 'Duplicate full declarations' mistake to distinguish same-entity repeated node objects (which JSON-LD merges per the live-verified W3C spec) from one @id genuinely reused for two different entities (a real semantic conflict).
-
Added a spec-grounded clarification that a bare {"@id": ...} node reference is valid JSON-LD syntax, not a parse error — the orphaned-reference problem is semantic incompleteness for the consumer, not invalid markup.
Full comparison unavailable — no prior snapshot was archived for this revision.