Schema Markup : Using Service and Webpage Types on the Same Page - schema.org

I have taken over the general administration of a business website. On the service pages, two separate instances of structured data are being loaded (the Service schema type, and the Webpage schema type).
<script type='application/ld+json'>
{
"#context": "http://schema.org/",
"#type": "Service",
"serviceType": "Service Type Here",
"alternateName": "Alternate Service Name Here",
"description": "Description Here",
"mainEntityOfPage": "https://www.WebsiteAddress.com/service-type",
"name": "Service Name"
}
</script>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebPage",
"name": "Webpage Name",
"url": "https://www.WebsiteAddress.com/service-type",
"inLanguage":"en-US",
"description": "Description Here",
"publisher": {
"name": "Business Name"
}
}
</script>
Could the current setup cause conflicts with how search engines interpret the page?
As most of the tags are duplicates, would it make more sense to remove the Webpage type schema markup and add the brand tag into the Service schema?
Interested to hear opinions on this.

About your Q. The short answer is YES => It's ok to declare two types (-or- more) on the same page (No "one rule" her - it's related to page structure/content).
"duplication" -
First As most of the tags are duplicates is a wrong sentence (One time the name related to webPage object and one time for service object). If in your specific case "service name" = "page name" it's ok to use the same value (This is the true semantic meaning of your content).
WebPage & Service
WebPage is a special type:
Every web page is implicitly assumed to be declared to be of type
WebPage. https://schema.org/WebPage
If you look at this issue in the microdata approach it's easier to understand the structure/idea of the sentence above.
a.The webpage (Again - Every page assumed to be of type WebPage):
<body itemscope="" itemtype="http://schema.org/WebPage">
<h1 itemprop="name">Our services</h1>
</body>
b.The service
<div itemscope itemtype="http://schema.org/TaxiService">
<h2 itemprop="name">Drive to airport</h2>
</div>
a & b - could look like this:
<body itemscope itemtype="http://schema.org/WebPage">
<h1 itemprop="name">Our services</h1>
<div itemscope itemtype="http://schema.org/TaxiService">
<h2 itemprop="name">Drive to airport</h2>
</div>
</body>
If page name = service name - you could do something like this:
<body itemscope itemtype="http://schema.org/WebPage">
<meta itemprop="name" content="Drive to airport">
<div itemscope itemtype="http://schema.org/TaxiService">
<h1 itemprop="name">Drive to airport</h1>
</div>
</body>
Nothing wrong her.
1/2. The page name is "Drive to airport" (true):
2/2. And the service name is "Drive to airport" (true):
If the service is the main entity of webPage this outline is a good start point (Close to your Q code example):
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebPage",
"name": "Our services",
"breadcrumb": "main > Our services",
"mainEntity":{
"#type": "service",
"name": "Drive to airport"
}
}
</script>

Related

Implementing multiple images in Article structured-data type

For example, there is a news article with 3 images. The first one — main picture, the other two — photos from social network.
I want: 1) define the first picture as main image. This one search engines should use for rich results.
2) Define other 2 images as related to the news topic.
#1 All images goes to Article.image property.
<html>
<head>
<title>Article headline</title>
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "NewsArticle",
"headline": "Article headline",
"image": [
"https://example.com/photos/photo1x1.jpg",
"https://example.com/photos/photo4x3.jpg",
"https://example.com/photos/photo16x9.jpg",
"https://example.com/photos/2.jpg",
"https://example.com/photos/3.jpg"
],
"datePublished": "2015-02-05T08:00:00+08:00",
"dateModified": "2015-02-05T09:20:00+08:00"
}
</script>
</head>
<body>
</body>
</html>
#2 Only first image goes to Article.image property, other two — Article.hasPart.
<html>
<head>
<title>Article headline</title>
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "NewsArticle",
"headline": "Article headline",
"image": [
"https://example.com/photos/photo1x1.jpg",
"https://example.com/photos/photo4x3.jpg",
"https://example.com/photos/photo16x9.jpg"
],
"datePublished": "2015-02-05T08:00:00+08:00",
"dateModified": "2015-02-05T09:20:00+08:00",
"hasPart": [
{
"#type": "ImageObject",
"url": "https://example.com/photos/2.jpg"
},
{
"#type": "ImageObject",
"url": "https://example.com/photos/3.jpg"
}
]
}
</script>
</head>
<body>
</body>
</html>
Which one is more correct?
Define other 2 images as related to the news topic.
Structured Data is highly dependent on the content of the linked web page. If we assume that your web page has the appropriate structure for three images, then, in this case, using the property about or subjectOf can help you. Embed a type that is most appropriate for the sub-subject. And for this type, set a separate image property. This can create rich results that present images for the subject of the entire article and images for sub-subjects of the same article. However, structured data depends on the details.

Is the homepage implied in [BreadcrumbList JSON LD + Schema.org]?

Looking at the examples Google provides here, the first breadcrumb seems to be already 1 level deep.
Am I correct to assume that the homepage is then determined to be the root domain? What if it's a subdomain?
The example code from the link above, quoted:
{
"#context": "https://schema.org",
"#type": "BreadcrumbList",
"itemListElement": [{
"#type": "ListItem",
"position": 1,
"name": "Books",
"item": "https://example.com/books"
},{
"#type": "ListItem",
"position": 2,
"name": "Authors",
"item": "https://example.com/books/authors"
},{
"#type": "ListItem",
"position": 3,
"name": "Ann Leckie",
"item": "https://example.com/books/authors/annleckie"
}]
}
under schema.org docs:
beginning with '1' for the first item in the list
https://schema.org/BreadcrumbList
No zero value (No way to declare "the zero item in the list").
This markup is ok/valid (In my list home = first item in the list):
home > blog
<ol itemscope itemtype="http://schema.org/BreadcrumbList">
<li itemprop="itemListElement" itemscope
itemtype="http://schema.org/ListItem">
<a itemprop="item" href="https://example.com/">
<span itemprop="name">Home</span></a>
<meta itemprop="position" content="1" />
</li>
<li itemprop="itemListElement" itemscope
itemtype="http://schema.org/ListItem">
<a itemprop="item" href="https://example.com/blog/">
<span itemprop="name">blog</span></a>
<meta itemprop="position" content="2" />
</li>
</ol>
SUM: Schema.org give semantic meaning for you content. Position 1 could be root-domain or sub-domain.
Rich Snippet:
Most of the times google omits "homepage" (name) from the snippet (Moz "real source code" example):
I think the best answer is to check how Google displays your page in the search results. The breadcrumb markup are suggestions for the way the url part of the search result is displayed.
I've seen markup including "home" page items causing poor looking results by showing "home" in the snippet.
While other times Google has understood that it should be ignored.
Safest bet, don't include the root. You also don't need to include the current page.

"position" property required for ItemList with Product list items?

I have a problem: Google’s Structured Data Testing Tool gives me an error:
Tag position doesn't exist. It's required.
I add it to the markup. Than I get this error:
Position property is not valid for an object of type Product
Here is my markup:
<table id="sale_table" itemscope="" itemtype="http://schema.org/ItemList">
<tbody>
<tr itemprop="itemListElement" itemscope="" itemtype="http://schema.org/Product">
<td class="sale_art_td" itemprop="productID">10496278</td>
<td class="sale_brand_td" itemprop="brand"><span itemprop="name ">--</span></td>
<td class="sale_name_td" itemprop="name">10496278 / Крышка трамблера Daewoo Nexia,Espero DD</td>
<td class="sale_am_td">1.00</td>
<td class="sale_price_td" itemprop="offers" itemscope="" itemtype="http://schema.org/Offer"><meta itemprop="priceCurrency" content="RUR"><span itemprop="price">341.50</span></td>
<td class="sale_buy_td">Купить<!--<img src="/upload/badge/sale_cart.png" />--></td>
<td class="hidden">
<meta itemprop="url" content="/partsearch/?q=10496278">
<span itemprop="description">Распродажа: 10496278 / Крышка трамблера Daewoo Nexia,Espero DD по цене 341.50</span>
</td>
</tr>
<tr itemprop="itemListElement" itemscope="" itemtype="http://schema.org/Product">
<td class="sale_art_td" itemprop="productID">76202sx0a12</td>
<td class="sale_brand_td" itemprop="brand"><span itemprop="name ">HONDA</span></td>
<td class="sale_name_td" itemprop="name">76202SX0A12</td>
<td class="sale_am_td">1.00</td>
<td class="sale_price_td" itemprop="offers" itemscope="" itemtype="http://schema.org/Offer"><meta itemprop="priceCurrency" content="RUR"><span itemprop="price">704.00</span></td>
<td class="sale_buy_td">Купить<!--<img src="/upload/badge/sale_cart.png" />--></td>
<td class="hidden">
<meta itemprop="url" content="/partsearch/?q=76202sx0a12">
<span itemprop="description">Распродажа: 76202SX0A12 по цене 704.00</span>
</td>
</tr>
</tbody>
</table>
This is not an error with your code. It just means that Google won’t display a certain Rich Snippet (or a similar feature) unless you provide this property.
However, the position property is not defined for the Product type, so this does not make any sense.
It seems that this is a new structured data feature from Google, which is not documented yet, as it links to a 404 page: List Page Carousels. Maybe it’s a work in progress and they didn’t mean to publish the check in their Testing Tool yet.
So I’d simply ignore this for now.
From my testing malefique is onto the right solution.
This code fully validates using the Structured Data testing tool:
{
"#context": "http://schema.org",
"#type": "ItemList",
"itemListOrder": "http://schema.org/ItemListOrderDescending",
"itemListElement": [
{
"#type": "ListItem",
"position": 1,
"item": {
"#type": "Product",
"name": "My product",
"url": "www.example.com",
"offers": {
"#type": "Offer",
"availability": "http://schema.org/InStock",
"price": "100.00",
"priceCurrency": "AUD"
}
}
}
]
}
I guess this is an implementation error on Google's side caused by non explicit documentation:
https://schema.org/itemListElement clearly states
Existing entities are best for a simple, unordered list of existing things in your data. ListItem is used with ordered lists when you want to provide additional context about the element in that list or when the same item might be in different places in different lists.
Note: The order of elements in your mark-up is not sufficient for indicating the order or elements. Use ListItem with a 'position' property in such cases.
At the same time is says Values expected to be one of these types are:
ListItem
Text
Thing
=> This means implicitly, that the position element can only be required for sorted lists, which in turn demand that the Thing element is contained inside a ListItem element, which offers the itemprop position.
It also means implicitly that if the ItemListElement is Text or Thing, the list should be considered Unordered.
This is the only way the documentation makes sense. I assume that implicit connection was missed.
So I guess the appropriate action is to file a bug report for the Structured Data Testing Tool and live with the warnings for now or nest the Product inside a ListItem element as a workaround.
I found http://schema.org/itemListElement
you have to specify the position like so <meta itemprop="position" content="1" />
There is an example at the bottom of the page.
try this
'#type': 'ListItem',
'position': 1,
'item':{
'#type': 'Product',
... product props
}
The fix is to stuff your product into a ListItem's item property. The ListItem gets the position property. Once you do that, it passes Google's SDTT.
NOTE: It is invalid to have a product offer on more than 1 URL/URI.
Build out a page (unique URL) for each product offer and that's where you put your structured data / schema.org product offer data; OR, put all your product offers on a single page (URL/URI) - never both. Otherwise, you'll get error All values provided for url must point to the same page.

Defining a bill or invoice using Google email markup

I know this can be done because i'm looking at an invoice from a telco in my gmail inbox mobile app but I don't know how to set the gmail markup / schema to make it happen.
The example I have shows:
August bill for xxxx
Total: $xxx, due MMM DD
$ Total amount due
$xxxx
Due date
DD MMM
Issuer
Telco X
Can anyone help?
I can't find any guidance on the email markup pages on Google.
It uses regular http://schema.org markup within the HTML of the email. See gmail markup reference.
Example adapted from google's gmail markup example:
<div itemscope itemtype="http://schema.org/Order">
<div itemprop="merchant" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Amazon.com"/>
</div>
<meta itemprop="orderNumber" content="123-4567890-1234567"/>
<meta itemprop="priceCurrency" content="USD"/>
<meta itemprop="price" content="259.99"/>
<div itemprop="acceptedOffer" itemscope itemtype="http://schema.org/Offer">
<div itemprop="itemOffered" itemscope itemtype="http://schema.org/Product">
<meta itemprop="name" content="Samsung Chromebook"/>
<meta itemprop="sku" content="B009LL9VDG"/>
<link itemprop="url" href="https://rads.stackoverflow.com/amzn/click/com/B009LL9VDG" rel="nofollow noreferrer"/>
<link itemprop="image" href="http://ecx.images-amazon.com/images/I/81H-DO3qX0L._SX522_.jpg"/>
</div>
<meta itemprop="price" content="249.99"/>
<meta itemprop="priceCurrency" content="USD"/>
<div itemprop="eligibleQuantity" itemscope itemtype="http://schema.org/QuantitativeValue">
<meta itemprop="value" content="1"/>
</div>
<div itemprop="seller" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Samsung Marketplace Store"/>
</div>
</div>
</div>
<div itemprop="priceSpecification" itemscope itemtype="http://schema.org/DeliveryChargeSpecification">
<meta itemprop="price" content="10.00"/>
<meta itemprop="priceCurrency" content="USD"/>
</div>
<link itemprop="url" href="https://www.amazon.ca/gp/css/summary/edit.html/orderID=123-4567890-1234567"/>
<div itemprop="potentialAction" itemscope itemtype="http://schema.org/ViewAction">
<link itemprop="target" href="https://www.amazon.ca/gp/css/summary/edit.html/orderID=123-4567890-1234567"/>
</div>
<link itemprop="orderStatus" href="http://schema.org/OrderStatus/OrderProcessing"/>
#AaronP, I've posted my findings and example in this issue similar to your question. Using schema.org/Invoice and schema.org/PayAction, I was able to get the email similar to what you received from Telco X. Keep in mind that this seems only active with Inbox and not Gmail.
<script type="application/ld+json">
[
{
"#context": "http://schema.org",
"#type": "Invoice",
"description": "January 2015 Acme Bill",
"url": "https://www.americanexpress.com",
"accountId": "xxxx-xxxx-xxxx-1234",
"potentialaction": {
"url": "https://example.com",
"#type": "PayAction"
},
"paymentDue": "2020-01-30",
"minimumPaymentDue": {
"#type": "PriceSpecification",
"price": "$15.00"
},
"totalPaymentDue": {
"#type": "PriceSpecification",
"price": "$200.00"
},
"paymentStatus": "payment due",
"provider": {
"#type": "Organization",
"name": "Acme Bank"
}
}
]
</script>
You should get this:

Google Webmaster Tools: "There was an error parsing your JSON-LD."

I have just logged into Google Webmaster Tools and am finding an error in structured data relating to a new WordPress theme I am using:
JSON-LD: There was an error parsing your JSON-LD.
The code it is referring to is:
<meta property="og:site_name" content="Townsville Nerds - Ph 0402 807 890" />
<script type='application/ld+json'>
execOnReady(function({{"#context":"http:\/\/schema.org","#type":"WebSite","url":"http:\/\/www.townsvillenerds.com\/","name":"Townsville Nerds - Ph 0402 807 890"}})
</script>
NOTE: In Webmaster Tools there is a red underscore under the "e" in the word "execOnReady".
Your data block does not contain valid JSON-LD (application/ld+json).
Instead of
<script type='application/ld+json'>
execOnReady(function({{"#context":"http:\/\/schema.org","#type":"WebSite","url":"http:\/\/www.townsvillenerds.com\/","name":"Townsville Nerds - Ph 0402 807 890"}})
</script>
it should be
<script type='application/ld+json'>
{"#context":"http:\/\/schema.org","#type":"WebSite","url":"http:\/\/www.townsvillenerds.com\/","name":"Townsville Nerds - Ph 0402 807 890"}
</script>
I guess you don’t need to escape the /, so it could be:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebSite",
"url": "http://www.townsvillenerds.com/",
"name": "Townsville Nerds - Ph 0402 807 890"
}
</script>