Google Custom Search Engine Schema.org structured data and returned results through API - schema.org

Here is my markup with rich snippets
<div vocab="http://schema.org" typeof="GovernmentOrganization">
<p>
<span property="logo"><img src="http://www.place.com/image.png" class="logo"/></span>
<span class="h2" property="name">Department Of Stuff And Things</span><br />
<span class="h4" property="department">State Agency</span><br />
http://www.place.com
</p>
<strong>Locations:</strong><br /><br />
<div property="location" typeof="GovernmentOffice">
<p property="location" typeof="PostalAddress">
Main Office<br />
<span property="streetAddress">555 Something Street Apt 2</span><br />
<span property="addressLocality">Jacksonville</span>
<span property="addressRegion">FL</span>
<span property="postalCode">11111</span><br />
<span property="addressCountry">US</span>
</p>
</div>
<strong>Services:</strong><br /><br />
<div property="hasOfferCatalog" typeof="OfferCatalog">
<div property="itemListElement" typeof="GovernmentService">
<p>
<strong><span property="name">Service 1</span></strong><br />
<span property="category">Web Based</span><br />
<span property="description">Get Some stuff and things</span><br />
https://www.place.com/Service1<br />
</p>
</div>
<div property="itemListElement" typeof="GovernmentService">
<p>
<strong><span property="name">Apply For Benefits</span></strong><br />
<span property="category">Phone Based</span><br />
<span property="description">This service helps you apply for the benefits you deserve</span><br />
https://www.place.com/Service1<br />
</p>
</div>
</div>
The structured data testing tool seems to organize and validate everything appropriately, Including my small collection of services (OfferCatalog). When doing a request to the Custom Search API and tacking on the :more:pagemap:GovernmentOrganization things seem to be OK and I get results I expect. But the JSON object for pagemap only includes the first level of my organization:
"pagemap": {
"GovernmentOrganization": [
{
"name": "Department Of Stuff And Things",
"department": "State Agency",
"url": "http://www.place.com"
},
Any ideas on why my related objects (GovernmentOffice / locations / OfferCatalog / GovernmentServices) are not being including? Is there a better way to organize and structure this for Google?

Consider this approach. Include the following JSON-LD script in the document. It can go anywhere but consider placing it before the RDFa DIV:
<script type="application/ld+json" id="">
{
"#context":
{
"#vocab": "http://schema.org/",
"#base": "http://www.place.com/"
},
"#graph": [
{
"#id": "_:ub220bL18C41",
"#type": "PostalAddress",
"addressCountry": "US",
"addressLocality": "Jacksonville",
"addressRegion": "FL",
"postalCode": "11111",
"streetAddress": "555 Something Street Apt 2"
},
{
"#id": "_:ub220bL4C1",
"#type": "GovernmentOrganization",
"department": "State Agency",
"hasOfferCatalog": {
"#id": "_:ub220bL6C40"
},
"location": {
"#id": "_:ub220bL17C33"
},
"logo": "",
"name": "Department Of Stuff And Things",
"url": "http://www.place.com"
},
{
"#id": "_:ub220bL17C33",
"#type": "GovernmentOffice",
"location": {
"#id": "_:ub220bL18C41"
}
},
{
"#id": "_:ub220bL6C40",
"#type": "OfferCatalog",
"itemListElement": [
{
"#id": "_:ub220bL12C17"
},
{
"#id": "_:ub220bL7C48"
}
]
},
{
"#id": "_:ub220bL12C17",
"#type": "GovernmentService",
"category": "Web Based",
"description": "Get Some stuff and things",
"name": "Service 1",
"url": "https://www.place.com/Service1"
},
{
"#id": "_:ub220bL7C48",
"#type": "GovernmentService",
"category": "Phone Based",
"description": "This service helps you apply for the benefits you deserve",
"name": "Apply For Benefits",
"url": "https://www.place.com/Service2"
}
]
}
</script>
You'll want to change #base to your site and decide how to organize your directory structure to manage your identifiers. Then change each blank node to the appropriate identifier. Then minimize the JSON-LD.
The JSON-LD is semantically identical to the RDFa. As such, you will be able to analyze the Google pagemap and decide which strategy works better for you. I don't expect Google to penalize the page if the JSON-LD is semantically identical to the HTML/RDFa markup.

As per the Google:
I believe you are seeing only one value of a attribute in JSON API.
I would like to update you that as per the design in JSON API we show only one attribute value, while in XML we show all values.
We already have a feature request #16696973 to display all the attribute values in JSON API. Currently I don't have an ETA when it will be implemented.
As a workaround you have to use XML API.

Related

How should I represent "global" events / observances / occasions in Schema.org?

I administer an educational site that includes a calendar of global events, but these are not "Events" in the sense that Schema.org's Event type considers them – they don't have a location, and they are observed across a wide area (e.g. a country, an continent, or worldwide). They are more like global anniversaries, occasions or observances. Examples include Earth Day, Chinese New Year, World Book Day, International Women's Day and so on.
In our initial attempt at introducing microdata for these calendar pages, I have used the Event type, but I'm aware that as many – or most – of these events don't have a definable location (in the sense that Schema.org represents a location), and are not "attended" in a physical or digital sense, they cannot be valid.
Is there a more appropriate type in the Schema.org vocabulary that I should use in this case? Is it inappropriate to try to represent them in Schema.org microdata at all?
Maybe Google's guide for an online event can help you, including an example:
<html>
<head>
<title>The Adventures of Kira and Morrison</title>
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "Event",
"name": "The Adventures of Kira and Morrison",
"startDate": "2025-07-21T19:00:00-05:00",
"endDate": "2025-07-21T23:00-05:00",
"eventStatus": "https://schema.org/EventScheduled",
"eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",
"location": {
"#type": "VirtualLocation",
"url": "https://operaonline.stream5.com/"
},
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"description": "The Adventures of Kira and Morrison is coming to Snickertown in a can't miss performance.",
"offers": {
"#type": "Offer",
"url": "https://www.example.com/event_offer/12345_201803180430",
"price": "30",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "2024-05-21T12:00"
},
"performer": {
"#type": "PerformingGroup",
"name": "Kira and Morrison"
},
"organizer": {
"#type": "Organization",
"name": "Kira and Morrison Music",
"url": "https://kiraandmorrisonmusic.com"
}
}
</script>
</head>
<body>
</body>
</html>
In addition, Schema has the beta version of the type VirtualLocation.

Adding booking meta data to Google Search

I can't for the life of me figure out how this company adding this meta data to their Google search.
Does anyone know how to add the data and booking links like the below image?
Thanks
What you are seeing in these search results is what Google defines as "Rich Results" more information can be viewed in Google's Structured Data documentation. Specifically Edgewater Medical center is taking advantage of the event functionality to define times and dates.
This can be verified by pasting the page's source in the Rich Results Test tool, results for this page can be viewed at
https://search.google.com/test/rich-results?utm_campaign=devsite&utm_medium=jsonld&utm_source=event&id=m1ZrUywePCZ_NglFJIjZfg
According to google documentation in order to make this happen you have to follow a few steps:
Ensure that Googlebot can crawl your event pages (meaning, your pages
aren't protected by a robots.txt file or robots meta tag).
Ensure that your server can handle increased crawl rate.
Make sure you follow the Google guidelines.
Add structured data to your event pages. Currently, the event experience on Google only supports pages that focus on a single event. We recommend focusing on adding markup to your event posting pages instead of pages that list schedules or multiple events.
An example of such "structured data" for a standard event is shown below:
<html>
<head>
<title>The Adventures of Kira and Morrison</title>
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "Event",
"name": "The Adventures of Kira and Morrison",
"startDate": "2025-07-21T19:00-05:00",
"endDate": "2025-07-21T23:00-05:00",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"eventStatus": "https://schema.org/EventScheduled",
"location": {
"#type": "Place",
"name": "Snickerpark Stadium",
"address": {
"#type": "PostalAddress",
"streetAddress": "100 West Snickerpark Dr",
"addressLocality": "Snickertown",
"postalCode": "19019",
"addressRegion": "PA",
"addressCountry": "US"
}
},
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"description": "The Adventures of Kira and Morrison is coming to Snickertown in a can’t miss performance.",
"offers": {
"#type": "Offer",
"url": "https://www.example.com/event_offer/12345_201803180430",
"price": "30",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "2024-05-21T12:00"
},
"performer": {
"#type": "PerformingGroup",
"name": "Kira and Morrison"
},
"organizer": {
"#type": "Organization",
"name": "Kira and Morrison Music",
"url": "https://kiraandmorrisonmusic.com"
}
}
</script>
</head>
<body>
</body>
</html>

Breadcrumb with non-linked level

I try to implement a JSON-LD breadcrumb for a web site with the following structure:
Home
Topic A (No content)
Article A1
Article A2
Topic B (No content)
Article B1
Article B2
Topic C (No content)
Article C1
Article C2
My problem is that all pages on level 2 (Topic A/B/C) are empty pages that can not be reached by the main navigation. People should not navigate to "Topic A" etc.
How can I express this behavior in my JSON-LD breadcrumb?
This is what my JSON-LD looks like for page "Article A1":
{
"#context": "https://schema.org",
"#type": "BreadcrumbList",
"itemListElement": [{
"#type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.com/"
},{
"#type": "ListItem",
"position": 2,
"name": "Topic A",
"item": ""
},{
"#type": "ListItem",
"position": 3,
"name": "Article A1",
"item": "https://example.com/topic-a/article-a1"
}]
}
When I try to validate the above code with https://search.google.com/structured-data/testing-tool it always complains:
itemListElement
#type ListItem
position 2
name Topic A
item Field item requires a value.
Specifying anything else than a URL will result in:
Value for field item must be a valid URL.
How can I describe that 2nd level pages are not reachable by a URL using JSON-LD?
The point of breadcrumbs is to see the current page in the hierarchy, and to navigate to its parent pages. Page-less entries shouldn’t appear there, because they can’t be navigated to.
Schema.org’s BreadcrumbList type is only meant for web pages (but such a page-less topic isn’t a web page, of course):
A BreadcrumbList is an ItemList consisting of a chain of linked Web pages, typically described using at least their URL and their name, and typically ending with the current page.
This is also what Google requires for their Breadcrumbs rich result (in case you want to get this feature):
A user can navigate all the way up in the site hierarchy, one level at a time, by starting from the last breadcrumb in the breadcrumb trail.
So, you could either omit the page-less topics in the BreadcrumbList, or make them actual pages.
If you don’t want them to exist as pages, you could still convey what the topic is (see example with about below), but I wouldn’t expect this data to get used by consumers that are interested in your breadcrumbs:
{
"#context": "http://schema.org",
"#type": "BreadcrumbList",
"itemListElement":
[
{
"#type": "ListItem",
"position": 1,
"item":
{
"#id": "https://example.com/",
"#type": "WebPage",
"name": "Home"
}
},
{
"#type": "ListItem",
"position": 2,
"item":
{
"#id": "https://example.com/article-a1",
"#type": "WebPage",
"name": "Article A1",
"about": {
"#type": "Thing",
"name": "Topic A"
}
}
}
]
}
HTML+RDFa:
<ol typeof="schema:BreadcrumbList">
<li property="schema:itemListElement" typeof="schema:ListItem">
<a property="schema:item" typeof="schema:WebPage" href="https://example.com/">
<span property="schema:name">Home</span>
</a>
<meta property="schema:position" content="1" />
</li>
<li property="schema:itemListElement" typeof="schema:ListItem">
<a property="schema:item" typeof="schema:WebPage" href="https://example.com/article-a1">
<span property="schema:name">Article A1</span>
<span property="schema:about" typeof="schema:Thing">
<meta property="schema:name" content="Topic A" />
</span>
</a>
<meta property="schema:position" content="2" />
</li>
</ol>

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.

Schema markup for logo

I have this markup for Dentist https://schema.org/Dentist
<div itemscope itemtype="http://schema.org/Dentist">
// address is ok
<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress">asdfd sf412</span>
<span itemprop="postalCode">12345</span>
<span itemprop="addressLocality">sadfsdf</span>
</span>
// this fails
<span itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<meta itemprop="url" content="logo.gif'; ?>" />
</span>
</div>
When trying to test code for itemprop="logo" https://schema.org/logo
Google testing gives me error: "A value for the url field is required."
What am I missing?
I don't want logo to be visible on page, thats why I have put it as meta.
The error in Google’s SDTT is about the Dentist item, not about the ImageObject item. You can see this from the nesting level, the url row is on the same level as logo and address.
So adding a url property to the Dentist item would get rid of the error.
<div itemscope itemtype="http://schema.org/Dentist">
<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress">asdfd sf412</span>
<span itemprop="postalCode">12345</span>
<span itemprop="addressLocality">sadfsdf</span>
</span>
<span itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<link itemprop="url" href="logo.gif" />
</span>
<link itemprop="url" href="http://example.com/" />
</div>
I changed the meta to link, because HTML5 and Microdata require that you use link (instead of meta) if the value is a URI.
Just in case if you are looking for a JSON-LD format, look over the below code and give it a shot.
"publisher": {
"#type": "Organization",
"name": "Lokaci",
"url": "https://lokaci.com",
"logo": {
"#type": "ImageObject",
"url": "https://res.cloudinary.com/lokaci/image/upload/v1580448186/logo/lokaci_logo_black-corp-comp_nzkooj.png"
}
},
Here is the full code if you wanna have a look, the schema micro-data was about a news article.
------------------full JSON-LD format below ----------------
{
"#context": "https://schema.org",
"#type": "NewsArticle",
"url": "https://lokaci.com/news/Diwali-Countdown-Offer-A-Brothers-Gift",
"publisher": {
"#type": "Organization",
"name": "Lokaci",
"url": "https://lokaci.com",
"logo": {
"#type": "ImageObject",
"url": "https://res.cloudinary.com/lokaci/image/upload/v1580448186/logo/lokaci_logo_black-corp-comp_nzkooj.png"
}
},
"dateline": "Laxminagar Delhi, 26 October 2019",
"headline": "Diwali Countdown Offer: A Brother’s Gift",
"mainEntityOfPage": "https://lokaci.com/newsroom",
"author": {
"#type": "Organization",
"name": "Lokaci",
"logo": "https://res.cloudinary.com/lokaci/image/upload/v1580448186/logo/lokaci_logo_black-corp-comp_nzkooj.png"
},
"image": "https://res.cloudinary.com/lokaci/image/upload/v1575284148/Newsroom/A-One-Salon-Lokaci-wins-Oppo-phone_dfvzdl.jpg",
"datePublished": " 26 October 2019",
"dateModified": " 26 October 2019",
"wordCount": 165,
"keywords": "Lokaci, News"
}