Actually I have a lack of understanding of how Schema.org objects are "composed" out of the given specification. Unfortunately I found no clear explanation so far.
Let’s take the JSON-LD example given at https://schema.org/SoldOut.
In "Example 1" we have given a property offers of type Offer. Within the only Offer, there is a price property specified ("13.00").
But if I look at the specification of object Offer given at https://schema.org/Offer there is no price property specified at all.
So my question is, where does it come from - the price property?
It seems that the Offer object merges the types Offer and PriceSpecification.
But why isn’t it then mentioned there in the #type property?
But if I look at the specification of object Offer given at https://schema.org/Offer there is no price property specified at all.
The Offer type does specify the price property.
The price property is listed on https://schema.org/Offer, and the Offer type is also listed under "Used on these types" on https://schema.org/price.
(Sometimes there’s a bug where a type page doesn’t list all properties, so maybe that’s why you didn’t see it.)
A type always specifies the properties of itself and the properties of all its parent types. So for Offer, you can use the properties from Offer, from Intangible, and from Thing:
Thing > Intangible > Offer
All available properties are listed in the first table on the type’s pages (unless the bug hits).
There are two kinds of price-property could be coming:
The first kind is the kind shown in the example of SoldOut. The second kind i show you in the following example, based on the SoldOuttoo
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Event",
"location": {
"#type": "Place",
"address": {
"#type": "PostalAddress",
"addressLocality": "Denver",
"addressRegion": "CO",
"postalCode": "80209",
"streetAddress": "7 S. Broadway"
},
"name": "The Hi-Dive"
},
"name": "SOLD OUT! Typhoon with Radiation City",
"offers": {
"#type": "Offer",
"availability": "http://schema.org/SoldOut",
"price": {
"#type": "PriceSpecification",
"price": "13.00",
"priceCurrency": "USD",
},
"url": "http://www.ticketfly.com/purchase/309433"
},
"startDate": "2013-09-14T21:30"
}
</script>
To say it in words, you could use price as stand-alone property, or as a part of the type PriceSpecification too. Both kinds of use are OK, the usage as a part of the type PriceSpecification is for cases, where you have to specify more properties as only the price and its currency, as listed under https://schema.org/PriceSpecification.
Related
I'm adding structured data to a course web page using Course json-ld markup.
The "provider" field I think is our Organization, because is an online course on our platform and we prepare the material to show during the lessons or, if this material is prepared from the Instructor/Speaker, is subject to approval/editing.
Here is the code:
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "Course",
"name": "Introduction to Trading Online",
"description": "Introductory Trading Online course laying out the basics.",
"image":"https://investire.biz/img/course/1500202_d7cc.jpg",
"provider": {
"#type": "Organization",
"name": "Investire.biz",
"sameAs": "https://investire.biz"
},
"inLanguage": "English",
"audience":{"audienceType":["Beginner trader","No specific knowledge"],"#type":"Audience"}
}
</script>
Which is the correct field for the instructor or speaker?
A Course can’t have a speaker, because it represents the creative work, not a specific instance of this course.
You can provide the instances with the hasCourseInstance property, which takes CourseInstance as value.
And a CourseInstance can have the instructor property:
A person assigned to instruct or provide instructional assistance for the CourseInstance.
Google mentions here that Carousel markups using ListItem with type, position and item is currently supported only for Recipe, Course and Article. So, doing this for other products is not much effective (looking at google search as the consumer).
Google in another page mentions this:
A category page listing several different products (or recipes, videos, or any other type). Each entity should be marked up using the relevant schema.org type, such as schema.org/Product for product category pages. However, if one item is marked, all items should be marked. Also, unless this is a carousel page, the marked items should not link out to separate details pages.
Note the statement about usage of proper Schema.org type, like Product and should not link to separate details pages.
So, for an online seller of shoes, then the category page will probably be like:
{
"#context": "http://schema.org",
"#type": "CollectionPage",
"#id": "https://www.example.com/cat1/cat2",
"url": "https://www.example.com/cat1/cat2",
"provider": {
"#type": "Organization",
"#id": "https://www.example.com#org"
},
"isPartOf": {
"#type": "WebSite",
"#id": "https://www.example.com#ws"
},
"name": "Running Shoes",
"hasPart": [
{
"#type": "Product",
"name": "shoe 1"
},{
"#type": "Product",
"name": "shoe 2"
},
...
]
}
I didn't use #id and url here, to conform with Google's statement about no link to separate details page. Don't feel comfortable about it.
Q1: Without these, how does this page semantically connect with the schemas of the respective products in other pages?
I didn't define the schema with ItemList as the items are not ordered and without position, SDTT raises error. (Infact, the above schema too raises error on SDTT with hasPart, stating: "Product is not a known valid target type for the hasPart property").
Q2: What is a better way to define this schema, to stay correct as per Schema.org and also not have Google raise errors?
Q3: If we use hasPart here for the products, can we on each of the product's ItemPage define isPartOf to include id-s to this CollectionPage (and other categories', if necessary) where the product is listed? Basically, that closes the loop, but as per schema, is that necessary or just one-way declaration (with 'hasPart' in category page) enough?
I have a real estate website which displays real estate properties for sale. For each page where a property is listed, I want to create JSON-LD code to display information about the property, using Schema.org.
I am not sure if there is a better type to use than Product for real estate listings here.
How can I add a custom attribute to describe the property?
Here is a JSON-LD structure for Product:
{
"#context": "https://schema.org/",
"#type": "Product",
"name": "address of the property ",
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"description": "description about the houese"
}
}
I want to be able to add other info like
Primary Features
How many bedrooms it has
How many bathrooms it has
If it is a smart home or not
etc...
Interior Features
Fireplace
Fireplace location
etc...
Exterior Features
The Lots Size
Fets
etc...
How can I add these custom attribute that describes the property using Schema.org?
If you want to provide data about real estate, you need to use a type that represents real estate. Probably Accommodation (Apartment, House, …) for your case.
If you want to convey that this real estate is a product, you need to provide the Product type in addition to the Accommodation type.
Then you can use properties from Accommodation as well as Product.
{
"#context": "https://schema.org/",
"#type": ["House", "Product"],
"offers": {
"#type": "Offer"
},
"numberOfRooms": 4
}
Custom properties about the real estate can be added with the additionalProperty property, and, if applicable, with the amenityFeature property.
My webapge
I am building a webpage for a conference. The page contains multiple objects like speaker (Person), or session (Event).
My problem
I would like to add semantic data to the page, so that search engines and social networks can easily understand its content. I would like to both describe the page as a whole, and parts of it - like a single session
My question
How do I mark up both the entire page and inner objects in a standard way?
Can I use multiple JSON-LD in the same page, or should I use JSON-LD for the page as a whole and other markups for inner objects?
Clarification, following the comments
Thanks for pointing out the answer to JSON-LD Schema.org: Multiple video/image page. However, it I am not sure where should I put the different JSON-LD objects so that each of them refers to a specific part of the document. Should they be linked using div ids? Should the <script> be placed inside the relevant div?
You can include multiple structured-data elements on a page if you wish as per Google's guideline:
https://developers.google.com/search/docs/guides/sd-policies#multiple-elements-on-a-page
The best way to tell whether it can parse your expected JSON-LD objects and attributes is to use their Structured Data Testing Tool
https://search.google.com/structured-data/testing-tool
I am not sure where should I put the different JSON-LD objects so that each of them refers to a specific part of the document.
With JSON-LD, the structured data is not "coupled" to the HTML. (That would be possible with the syntaxes Microdata and RDFa, but even there, after extracting the structured data, it’s of no relevance anymore on which HTML elements it was specified.)
If you have a page about two persons, you would just provide one WebPage and two Person objects. To be able to make statements about these objects from other places, it’s a good practice to give them URIs, which can be specified with #id. For the WebPage, the URI would typically be the canonical URL of the page.
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebPage",
"#id": "",
"about": [
{
"#type": "Person",
"#id": "#person-1"
},
{
"#type": "Person",
"#id": "#person-2"
}
]
}
</script>
Theoretically, there could be a property which allows you to reference the HTML elements which describe the entity. Schema.org currently has properties like that in Pending, which are used for SpeakableSpecification (Pending): cssSelector (Pending) (using CSS selectors to reference the elements), xpath (Pending) (using XPath to reference the elements). But these can’t be used for other cases (as currently defined). So you would have to define your own property for this purpose.
Should they be linked using div ids?
You could provide the id value in the object’s url property. It doesn’t "link" the HTML to the structured data, though. It just conveys: You can find information about the entity described by this node object by following this URL.
Often each entity has its own page, but it’s perfectly fine to describe multiple entities on the same page, of course.
Expanding the example from above:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebPage",
"#id": "",
"about": [
{
"#type": "Person",
"#id": "#person-1",
"url": "#about-person-1"
},
{
"#type": "Person",
"#id": "#person-2",
"url": "#about-person-2"
}
]
}
</script>
Should the <script> be placed inside the relevant div?
For the structured data, it makes no difference where in the HTML document the script elements are placed.
You could place all objects in one script element (like in the examples above), or you could use multiple script elements, but then you should reference their #id values so that you can still make use of properties like about (example in my answer linked above). It makes no difference semantically.
Below is a snippet from my JSON-LD for a site I'm working on.
I cannot get it to validate though as it says that there "The value provided for office must be a valid contact type." How do I make this a valid contact type? I can't find any documentation on this.
<script type='application/ld+json'>
{
"#context": "http://www.schema.org",
"#type": "EntertainmentBusiness",
"contactPoint": {
"#type": "ContactPoint",
"contactType": "office",
"telephone": "+44 (0)1234 567890"
}
}
</script>
The contactType property expects text and doesn’t recommend any values, so using "office" is perfectly fine.
But if you want to get Google’s Corporate Contacts feature, you have to provide a value that Google recognizes:
"customer support", "technical support", "billing support", "bill payment", "sales", "reservations", "credit card support", "emergency", "baggage tracking", "roadside assistance", "package tracking"
(Edit: They seem to have updated their documentation, and now they no longer list "customer support", but "customer service" instead.)
As you can see, "office" is not among them.
If you don’t care for this Google search result feature, you can keep it like that.