How to use multiple elements in JSON-LD [closed] - schema.org

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have a page describing a tourist attraction (TouristAttraction). Since I also want to add breadcrumb informations, I would need to add WebPage as well.
What is the way to go, for adding both infos:
Should I use WebPage and add the TouristAttraction as mainEntity?
Should I create 2 separate JSON-LD script blocks with separate
WebPage and TouristAttraction blocks?
And when using 2 entities:
Do I have to provide the main informations (name, image, rating, etc.) in both entities, or just in one (which one)?

#unor's answer is almost correct, but if you are doing it for google serp's, only splitting it up into separate json-blocks (or graph notation) will give the best result.
Let's say you want to use the Recipe entity to get google's rich snippet for Recipies in the serps you would do it like so:
<script type="application/ld+json">
{
"#context":"https:\/\/schema.org",
"#type":"Recipe",
"name":"Example",
"image":"https:\/\/www.example.com"
}
</script>
In google's Structed Data Testing Tool you will get a preview button for it:
If you now want to add other information from other entities (like breadcrumb), you have to use separate JSON-LD blocks, otherwise you will not get the preview button. So for example
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "ItemPage",
"breadcrumb": {
"#type": "BreadcrumbList"
},
"mainEntity": {
"#type":"Recipe",
"name":"Example",
"image":"https:\/\/www.example.com"
}
}
</script>
is valid, but will not show preview button.
But if you split it up, it will show to separate entities and also the preview button:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "ItemPage",
"breadcrumb": {
"#type": "BreadcrumbList"
}
}
</script>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type":"Recipe",
"name":"Example",
"image":"https:\/\/www.example.com"
}
}
</script>
Same works for Array-Notation:
<script type="application/ld+json">
[
{
"#context": "http://schema.org",
"#type": "ItemPage",
"breadcrumb": {
"#type": "BreadcrumbList"
}
},
{
"#context": "http://schema.org",
"#type":"Recipe",
"name":"Example",
"image":"https:\/\/www.example.com"
}
]
</script>
And graphs:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#graph":
[
{
"#type": "ItemPage",
"breadcrumb": {
"#type": "BreadcrumbList"
}
},
{
"#type":"Recipe",
"name":"Example",
"image":"https:\/\/www.example.com"
}
]
}
</script>
Credits goes to #unor (see also How do you combine several JSON-LD markups?)

Using mainEntity is of course preferable to not using it, as more data (if accurate) is generally better than less data.
But you can use mainEntity in both cases, no matter if you use one or multiple script elements. In the first case, you can simply nest the items. In the second case, you can make use of URI references.
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "ItemPage",
"breadcrumb": {
"#type": "BreadcrumbList"
},
"mainEntity": {
"#type": "TouristAttraction"
}
}
</script>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "ItemPage",
"breadcrumb": {
"#type": "BreadcrumbList"
},
"mainEntity": {"#id": "#content"}
}
</script>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "TouristAttraction",
"#id": "#content"
}
</script>
(And there are other ways, too.)
No matter which way you go, the ItemPage and the TouristAttraction are different entities, of course. So if you add aggregateRating to the ItemPage, it’s for the rating of the page, and if you add it to the TouristAttraction, it’s for the rating of the attraction. For properties that would take the same value, it can still make sense to add them to both entities, as a consumer might only be interested in one of the entities and ignore the other one.

WebPage is implicit for a Web Page, so you don't need to specifically add it.
You can define a BreadcrumbList as a top level entity and systems will understand it is an entity within the WebPage.
For the entity that you want to be considered main, you can also make it a top level entity and state it is the main entity using mainEntityOfPage with its id set to the URL of the page.

Related

Generating a Json schema with Google Shopping custom label

I am trying to add a custom label 0 shopping attribute to my Json schema but I don't get the this new attribute on my products.
I tried:
<script type="application/ld+json">
{
"#context": "https://schema.org/",
"#type": "Product",
"name": "Auvers - Van Gogh",
"sku":"artworkid[2316]-product[canvas]",
"mpn":"artworkid[2316]-product[canvas]",
"tags": [{
"custom_label_0": "Fine Art"
}
],
And also:
<script type="application/ld+json">
{
"#context": "https://schema.org/",
"#type": "Product",
"name": "Auvers - Van Gogh",
"sku":"artworkid[2316]-product[canvas]",
"mpn":"artworkid[2316]-product[canvas]",
"customLabel0": "Fine Art",
How to set this attribute with the structured data?
I didn't find any infos from the custom label support from Google:
https://support.google.com/merchants/answer/6324473?hl=en#zippy=%2Cexample-values

Can I use #id to join multiple JSON-LD scripts to a valid object?

Is this valid? I need an opportunity to join diffrent script blocks on one page to a valid object.
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Product",
"#id": "#111",
"description": "Test description",
"name": "My Product"
}
</script>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Product",
"#id": "#111",
"aggregateRating": {
"#type": "AggregateRating",
"ratingValue": "3.5",
"reviewCount": "11"
}
}
</script>
why should these scripts be joined? They describe the same product and are partly redundant.
But if you are looking for possibility to join scripts by id - yes, it exists. I.e. you have two scripts: first - product and its rating, second - organization offering this product. In this case the joining would look like:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Organization",
"makesOffer": {
"#type": "Offer",
"itemOffered": {
"#type": "Product",
"#id": "https://www.example.com#111"
}
}
}
</script>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Product",
"id": "https://www.example.com#111",
"aggregateRating": {
"#type": "AggregateRating",
"ratingValue": "3.5",
"reviewCount": "11"
}
}
</script>
I often do that when the review system adds its own markup separately to the product markup. It works fine.
You can test it in the Structured Data Testing Tool. It should merge the two into one.

What is the correct use of mainEntityOfPage schema

I am writing structured data for a magazine. I got this under the Article type:
"mainEntityOfPage": {
"#type": "WebPage",
"#id": " https://www.example.com/category" //category of the article
},
I thought I would mark the category of the article using this. Is this the correct way of using mainEntityOfPage?
No, the value should be the WebPage dedicated to the Article. Both items would typically have the same url, but possibly different #id values (see URL of page vs. post).
{
"#context": "http://schema.org",
"#type": "Article",
"#id": "/articles/42#this",
"url": "/articles/42",
"mainEntityOfPage": {
"#type": "ItemPage",
"#id": "/articles/42",
"url": "/articles/42"
}
}
It might become clearer when looking at the inverse property mainEntity. You would have a WebPage for the current page and provide the mainEntity property to convey what the primary entity on this page is:
{
"#context": "http://schema.org",
"#type": "ItemPage",
"mainEntity": {
"#type": "Article"
}
}
When using mainEntityOfPage instead of mainEntity, you simply switch subject and object.

Schema.org Character's URL for a PerformanceRole's entry

From Schema.org PerformanceRole JSON-LD example:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Movie",
"name": "Ghostbusters",
"sameAs": "http://en.wikipedia.org/wiki/Ghostbusters",
"actor": {
"#type": "PerformanceRole",
"actor": {
"#type": "Person",
"name": "Bill Murray"
},
"characterName": "Dr. Peter Venkman"
}
}
</script>
I can add a sameAs for each Person and thus have a reference/profile URL for each actor/actress involved with the movie.
Could I have the same for the Character performed by the actors?
In the example above Dr. Peter Venkman could have a link to something like this, a page with information specifically about that Character, regardless of the actor/actress interpreting him.
But, as far as I know, the characterName Property only accepts raw text.

Multiple #types together or in separate script tags?

I'm trying to wrap my head around this and I've read through several tutorials including schema.org documentation and Googles structured data guides and I can't find a clear answer on this. It's intuitive how to do this with microdata but not so much using JSON-LD. Let's say I have a website that is a local business and I offer products for sale. How would I combine both the LocalBusiness and Products into the same JSON-LD block of code? They are separate objects as far as my understanding.
Would the code look more like this...
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "LocalBusiness",
"name": "My Business"
}
{
"#context": "http://schema.org",
"#type": "Product",
"name": "My Proudct"
}
</script>
or in separate script tags like this...
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "LocalBusiness",
"name": "My Business"
}
</script>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Product",
"name": "My Proudct"
}
</script>
or something else altogether?