SchemaValid
ENDE
Structured Data

How to Combine Multiple JSON-LD Schema Types on One Page

Published: 9 min read
Contents

You've got an Organization block on the homepage, a Product block on every category page, and now someone wants a BreadcrumbList too. Can one page carry more than one schema type without Google ignoring half of it? Yes, and Google says so directly in its structured data guidelines. If you've read our piece on why valid schema markup doesn't guarantee rich results, you know passing validation isn't the finish line. Combining types adds a second layer to that: doing it wrong doesn't throw an error, it just quietly doesn't work.

Most guides on this question either cite no source or show no code you can actually paste and test. This one does both, straight from Google and the W3C spec.

Does Google even allow more than one schema type on a page?

Yes, and Google defines the exact scenario in its General Structured Data Guidelines: "multiple items on a page" means more than one kind of thing sharing the same URL. Google's own example is a recipe page that also carries a how-to video for that recipe, plus breadcrumbs. Three types, one page, and the guidelines say Google Search "understands multiple items on a page, whether you nest the items or specify each item individually."

That sentence names two supported patterns, not one. Nesting means a main item with additional items grouped underneath it, like a Recipe with a nested Video. Individual items means each type sits in its own separate block, flat on the page. Which one fits depends on whether the entities actually have a real relationship in the schema.org vocabulary, the question the rest of this article answers.

One rule rides along with this: mark up multiple reviews on a page, and Google expects all of them, not a curated subset averaging five stars. The completeness requirement applies per item type, nested or not.

The three ways to actually write it

Three mechanisms produce the same visible outcome, a page with multiple typed entities, but they aren't interchangeable, and the choice isn't just style.

The first is the obvious one: multiple separate <script type="application/ld+json"> tags on the page. Google's own intro to structured data describes JSON-LD as script tags in the head or body, no cap given. The second is @graph, a JSON-LD 1.1 keyword defined in the W3C Recommendation (16 July 2020, section 4.9, "Named Graphs"): one script tag holding an array of otherwise-unrelated typed nodes under one shared @context. The third isn't a keyword, it's an ordinary schema.org property whose value happens to be a typed object, like Article.author holding a full Person node.

MethodScript tagsThe mechanismBest forSource
Separate blocksOne per typeEach type is its own independent JSON-LD documentTypes with zero relationship to each otherGoogle, Intro to structured data
@graphOneA shared array of sibling nodes under one @contextCo-equal entities the vocabulary doesn't link (Organization + BreadcrumbList)W3C JSON-LD 1.1, §4.9
Nested propertyOne (usually)An ordinary property whose value is a typed objectReal parent-child relationships the vocabulary already defines (Article.author)Google, March 2023 Office Hours

An Organization type and a BreadcrumbList type have no property connecting them. You can write two separate script tags for those, or fold them into one @graph. Either is valid. What you can't do is nest one inside the other, because schema.org never defined Organization.breadcrumb or anything close to it.

Nesting vs. @graph: how to tell which one your case needs

Here's the actual test, simpler than most explanations make it sound: does the vocabulary itself define a property that takes the other type as its value? If yes, nest. If no, use @graph or separate blocks.

Article.author expects a Person (or Organization). That's a real, documented property, so putting the full Person object inside the author field is genuine nesting, containment the vocabulary intended. Google's Lizzi Sassman confirmed exactly this in the March 2023 SEO Office Hours transcript: "Nesting your structure data can help us understand what the main focus of the page is. For example, if you put recipe and review at the same level, it's not as clear as telling us that the page is a recipe with a nested review... the primary purpose of the page would be a recipe and that the review is a smaller component of that."

A narrower version goes back to 2019, when Google's own account on X said multiple types are fine, but not all might display together, as reported by Search Engine Roundtable.

Organization and BreadcrumbList don't have that relationship. Neither type takes the other as a property value, so nesting one inside the other would invent a connection that doesn't exist. @graph is the honest structure: both sit as flat, equal siblings inside one container, sharing one @context instead of two tags each repeating it. Our Person schema piece covers the reverse case, real nesting where the property already exists.

Sibling entities in @graph vs. a genuinely nested propertyOn the left, an @graph container holds Organization and BreadcrumbList side by side as equal, unconnected siblings, one script tag, one shared context, no parent-child relationship between the two. On the right, an Article box contains a smaller Person box through the author property, a real containment defined by the schema.org vocabulary itself, not by @graph. Source: W3C JSON-LD 1.1 Recommendation, 16 July 2020.@graphsibling entities, one script tag"@graph": [ ... ]Organization@typeBreadcrumbList@typeSame level. No property connects them.Nested property valueparent contains childArticleauthorPerson@typeContained because Article.author expects a Person.@graph bundles equal entities (JSON-LD/W3C keyword); nested values use whatever property the vocabulary already defines. Source: W3C JSON-LD 1.1 spec, 2020.

What actually breaks

Two failure modes are documented or directly reasoned from the mechanics above. Everything else you'll read about "too many JSON-LD blocks confusing Google" or plugin conflicts isn't something Google or the JSON-LD spec has actually published.

The first is Google's own worked example: unlinked related items. If a recipe and its how-to video sit on the same page but nothing ties them together, Google's guidelines state plainly that "Google Search may not know that it can show the video as a Recipe rich result." Two valid blocks on the same page, and Google still can't connect them without an explicit signal.

@id collisions merge entities you meant to keep separate

This follows from how @id works in the JSON-LD spec (W3C, section 3.3, "Node Identifiers"): an @id identifies and deduplicates a node. It's not a Google-published warning, it's a mechanical consequence. Give two genuinely different entities, say two unrelated Organizations, the same @id by accident, and processors treat them as one subject. Their properties collide into a single node instead of staying as two. Your JSON-LD will validate happily the whole time, quietly describing the wrong company.

One more caveat before you assume two valid types will render together: Google's guidelines say plainly that "Google does not guarantee that your structured data will show up in search results, even if your page is marked up correctly," and back in 2019 Google's own account said it directly, that it "may not be able to display all types together" on one page. Sassman's Office Hours answer above makes the same point at the feature level: right now, carousels only support course, movie, recipe, and restaurant, so check the specific feature's documentation before assuming your combination is one of the supported ones. FAQ rich results are the clearest recent case: the type still validates, but as we covered in FAQ Schema in 2026, Google stopped showing that rich result entirely.

Using @id to point at the same entity twice instead of repeating it

Google's recipe-and-video example above is the model for the fix, too. Give the Recipe and the Video a shared @id, and Google can read that as "this video is about this recipe": @id cross-references rather than duplicates.

That generalizes cleanly, though this next part is our own extension of the mechanism, not a Google-published example. A WebSite's publisher and a page's Organization often describe the exact same company. Instead of writing that Organization twice, give it one @id and reference it from both places.

EntityExample @id valueReferenced from
Organizationhttps://example.com/#organizationWebSite.publisher, and any other block naming the same company
WebSitehttps://example.com/#websitemainEntityOfPage, or a Person.worksFor pointing back at the site
Recipehttps://example.com/recipe/#recipeThe paired VideoObject's about (Google's own documented pattern)

Whether a search engine uses this generalized version the way it uses Google's own recipe/video pairing is genuinely unclear. What's confirmed is the mechanism itself: identical @id values mean identical entities, by spec, everywhere JSON-LD gets processed. What Google specifically rewards beyond its one documented case isn't something Google has spelled out.

Validate before you ship

None of the above matters if the JSON-LD doesn't parse. A single missing comma inside an @graph array can invalidate every node in it, not just the broken one, because they all share one script tag.

Run the finished markup through our Schema Validator before it goes live: paste the page URL or the raw JSON-LD, and it flags whether the structure parses and whether each type carries what its rich result requires. It won't tell you whether Google chooses to render the result, but it rules out the syntax problem before you spend time chasing a display issue that was never a display issue.

Frequently asked questions

Can I use multiple JSON-LD script tags on the same page?
Yes. Google's guidelines describe supporting multiple items on a page, and JSON-LD script tags aren't capped in number. Separate tags work fine for types with no relationship to each other.
What does @graph actually do?
@graph is a JSON-LD 1.1 keyword that lets one script tag hold an array of typed nodes under a single shared @context, instead of repeating the context across separate tags. It's for entities that sit as equals, not parent-child relationships.
Do I need @id on every entity?
No, but you need it on any entity you want to cross-reference or reuse. Google's own example uses a shared @id to link a Recipe and its paired video. Without that shared @id, Google's guidelines say it may not recognize the two belong together.
Can nested schema hurt me if I get it wrong?
Nesting itself isn't risky when the vocabulary defines the property you're using, like Article.author taking a Person. It becomes a problem if you invent a nested relationship the vocabulary doesn't define, or reuse an @id across two entities that are actually different, merging their properties.
Should I nest Organization inside BreadcrumbList, or the other way around?
Neither. schema.org doesn't define a property linking the two, so nesting either one inside the other invents a relationship that doesn't exist. Use @graph or two separate script tags instead.
Will two valid rich result types always show up together in search results?
Not necessarily. Google's guidelines note that even correctly combined, valid structured data doesn't guarantee both types will display together on the results page. Check the specific feature's own documentation first.

Related articles