Reputation: 640
Is there a way to describe the properties of each dish in a restaurantmenu?
These fields in particular: name, description, price
Or does one have to pray that google interprets the data correct when you have indicated the url of the menu in the restaurant properties?
Upvotes: 3
Views: 1308
Reputation: 1200
That is really good news! So, here I am to share something I've been waiting for a looong time myself.
If you've been dreaming of a proper method which allows the markup of multiple Restaurant Menus with along Menu Sections or even Offers differentiation, you'll be amazed with the refreshed schema.org/restaurant structuring markup possibilities.
The first thing you'll notice when you visit the schema.org/Restaurant page is that the menu property has been replaced with the hasMenu property, which now supersedes the still valid menu one.
So, straight to the point:
On every page of the website, it is recommended to point search engines in the right direction as to where the menu can be found. Here's a nice article that covers much of what I've put together here.
Google’s guidelines states that we should only mark up content that’s visible on the page, we can’t exactly include the entire menu in our home page markup unless the entire menu is published there. Instead, we’ll simply use the hasMenu property on the home page to point to the menu page, like this:
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "WebSite",
"name": "Your Restaurant's Name",
"url": "http://your-restaurant.com/",
"publisher": {
"@type": "Restaurant",
"name": "Your Restaurant's Name",
"hasMenu": "http://your-restaurant.com/menu/",
"logo": "http://.....
In fact, on any page of your website that includes some schema markup, you could use the hasMenu property to point to the URL of the menu page.
When you have more than one menu:
“hasMenu”: [
{
“@type”: “Menu”,
“name”: “Breakfast”,
“url”: “http://your-restaurant.com/breakfast-menu/”
},
{
“@type”: “Menu”,
“name”: “Lunch”,
“url”: “http://your-restaurant.com/lunch-menu/”
},
{
“@type”: “Menu”,
“name”: “Dinner”,
“url”: “http://your-restaurant.com/dinner-menu/”
}
],
...
Switching our attention to the actual menu page, let’s say that the menu was only served between 5:00pm and 11:00pm. So, on the menu page, our markup would begin like this:
<script type=”application/ld+json”>
{
“@context”: “http://schema.org”,
“@type”: “Menu”,
“name”: “Our Menu”,
“mainEntityOfPage”: “http://your-restaurant.com/menu/”,
“inLanguage”: “English”,
“offers”: {
“@type”: “Offer”,
“availabilityStarts”: “T17:00”,
“availabilityEnds”: “T23:00”
},
Next, we can begin marking up the various sections of the menu and the individual menu items. First, we’ll start with the appetizers. For the first appetizer, we’ll include in our markup the name, a brief description, and the price, which should be the minimum for any menu item. In our second appetizer markup example, we’ll also include an image, the nutritional information, and the fact that it’s gluten-free:
“hasMenuSection”: [
{
“@type”: “MenuSection”,
“name”: “Appetizers”,
“hasMenuItem”: [
{
“@type”: “MenuItem”,
“name”: “Fried Eggplant”,
“description”: “Served with Italian red gravy.”,
“offers”: {
“@type”: “Offer”,
“price”: “7.95”,
“priceCurrency”: “USD”
}
},
{
“@type”: “MenuItem”,
“name”: “Fried Calamari”,
“description”: “Served with Italian red gravy or honey mustard.”,
“image”: “http://your-restaurant.com/images/fried-calamari.jpg”,
“suitableForDiet”: “http://schema.org/GlutenFreeDiet”,
“nutrition”: {
“@type”: “NutritionInformation”,
“calories”: “573 calories”,
“fatContent”: “25 grams”,
“carbohydrateContent”: “26 grams”,
“proteinContent”: “61 grams”
},
“offers”: {
“@type”: “Offer”,
“price”: “7.95”,
“priceCurrency”: “USD”
}
}
]
},
Let’s say we’ve marked up all of the appetizers and we’re ready to begin marking up the next menu section, which in our case are the soups. Sometimes menu items such as soups are available in two or more sizes. We can mark up the available options by using a separate offer markup for each along with the eligibleQuantity property, like this:
{
“@type”: “MenuSection”,
“name”: “Soups”,
“hasMenuItem”: [
{
“@type”: “MenuItem”,
“name”: “Lobster Bisque”,
“offers”: [
{
“@type”: “Offer”,
“price”: “6.75”,
“priceCurrency”: “USD”,
“eligibleQuantity”: {
“@type”: “QuantitativeValue”,
“name”: “Cup”
}
},
{
“@type”: “Offer”,
“price”: “9.95”,
“priceCurrency”: “USD”,
“eligibleQuantity” : {
“@type”: “QuantitativeValue”,
“name”: “Bowl”
}
}
]
},
{
“@type”: “MenuItem”,
“name”: “Creole Seafood Gumbo”,
“offers”: [
{
“@type”: “Offer”,
“price”: “6.75”,
“priceCurrency”: “USD”,
“eligibleQuantity”: {
“@type”: “QuantitativeValue”,
“name”: “Cup”
}
},
{
“@type”: “Offer”,
“name”: “Bowl”,
“price”: “9.95”,
“priceCurrency”: “USD”,
“eligibleQuantity” : {
“@type”: “QuantitativeValue”,
“name”: “Bowl”
}
}
]
}
]
},
After we’ve marked up all of the soup items, we can move on to marking up the other menu sections and items using the same format. And that’s it. Putting it all together, our JSON-LD menu markup would look something like this:
<script type=”application/ld+json”>
{
“@context”:”http://schema.org”,
“@type”:”Menu”,
“name”: “Our Menu”,
“url”: “http://your-restaurant.com/menu/”,
“mainEntityOfPage”: “http://your-restaurant.com/menu/”,
“inLanguage”:”English”,
“offers”: {
“@type”: “Offer”,
“availabilityStarts”: “T17:00”,
“availabilityEnds”: “T23:00”
},
“hasMenuSection”: [
{
“@type”: “MenuSection”,
“name”: “Appetizers”,
“hasMenuItem”: [
{
“@type”: “MenuItem”,
“name”: “Fried Eggplant”,
“description”: “Served with Italian red gravy.”,
“offers”: {
“@type”: “Offer”,
“price”: “7.95”,
“priceCurrency”: “USD”
}
},
{
“@type”: “MenuItem”,
“name”: “Fried Calamari”,
“description”: “Served with Italian red gravy or honey mustard.”,
“image”: “http://your-restaurant.com/images/fried-calamari.jpg”,
“suitableForDiet”: “http://schema.org/GlutenFreeDiet”,
“nutrition”: {
“@type”: “NutritionInformation”,
“calories”: “573 calories”,
“fatContent”: “25 grams”,
“carbohydrateContent”: “26 grams”,
“proteinContent”: “61 grams”
},
“offers”: {
“@type”: “Offer”,
“price”: “7.95”,
“priceCurrency”: “USD”
}
}
]
},
{
“@type”: “MenuSection”,
“name”: “Soups”,
“hasMenuItem”: [
{
“@type”: “MenuItem”,
“name”: “Lobster Bisque”,
“offers”: [
{
“@type”: “Offer”,
“price”: “6.75”,
“priceCurrency”: “USD”,
“eligibleQuantity”: {
“@type”: “QuantitativeValue”,
“name”: “Cup”
}
},
{
“@type”: “Offer”,
“price”: “9.95”,
“priceCurrency”: “USD”,
“eligibleQuantity” : {
“@type”: “QuantitativeValue”,
“name”: “Bowl”
}
}
]
},
{
“@type”: “MenuItem”,
“name”: “Creole Seafood Gumbo”,
“offers”: [
{
“@type”: “Offer”,
“price”: “6.75”,
“priceCurrency”: “USD”,
“eligibleQuantity”: {
“@type”: “QuantitativeValue”,
“name”: “Cup”
}
},
{
“@type”: “Offer”,
“name”: “Bowl”,
“price”: “9.95”,
“priceCurrency”: “USD”,
“eligibleQuantity” : {
“@type”: “QuantitativeValue”,
“name”: “Bowl”
}
}
]
}
]
},
{
“@type”: “MenuSection”,
“name”: “Pastas”,
“description”: “Entrées served with dinner salad or a cup of soup of the day.”,
“hasMenuItem”: [
{
“@type”: “MenuItem”,
“name”: “Veal Parmigiana”,
“description”: “Tender cuts of paneed veal crowned with golden fried eggplant, Italian red gravy, mozzarella, and parmesan; served with spaghetti.”,
“offers”: {
“@type”: “Offer”,
“price”: “17.95”,
“priceCurrency”: “USD”
}
},
{
“@type”: “MenuItem”,
“name”: “Eggplant Parmigiana”,
“description”: “Pan fried eggplant layered and topped with Italian red gravy, mozzarella, and parmesan baked until bubbly; served with spaghetti.”,
“offers”: {
“@type”: “Offer”,
“price”: “14.95”,
“priceCurrency”: “USD”
}
}
]
}
]
}
</script>
I realize that not every restaurant menu scenario is perfectly covered with these new menu properties and types, but hopefully you now at least have plenty to get started with. Keep in mind, too, that the Schema.org vocabulary continues to evolve and so will this particular area of schema. You're welcome to participate in the evolution of Schema.org through the discussions on Github. If you think that you have a great suggestion, please feel free to join the conversation.
Upvotes: 2
Reputation: 96697
The vocabulary Schema.org does not (yet) offer a type for representing restaurant menus or single menu items.
Their menu
property expects text or URL as value. If there should ever be a type for menus, it would become another expected value.
The issue Extension Proposal: FoodProduct and Restaurant Menu with FoodProducts. asked for this. It got closed, referencing the broader issue Create a new Food type (help further with foodWarning and recipeIngredient). It’s still under discussion.
If you need something now, you could use the hasOfferCatalog
property that references an OfferCatalog
type (representing the menu, or grouped parts of the menu) and the Offer
type (representing a single menu item, with a price).
For example:
<div vocab="http://schema.org/" typeof="Restaurant">
<section property="hasOfferCatalog" typeof="OfferCatalog">
<h1 property="name">Menu</h1>
<ul>
<li property="itemListElement" typeof="Offer">
<b property="name">Bread</b> –
<span property="price">1.50</span>
<meta property="priceCurrency" content="EUR" />
</li>
<li property="itemListElement" typeof="Offer">
<b property="name">Water</b> –
<span property="price">1.00</span>
<meta property="priceCurrency" content="EUR" />
</li>
</ul>
</section>
</div>
If you want to use the menu
property, too, you could add a div
that encloses the OfferCatalog
. The value for menu
would then be the textual content.
<div vocab="http://schema.org/" typeof="Restaurant">
<div property="menu">
<section property="hasOfferCatalog" typeof="OfferCatalog">
<!-- … -->
</section>
</div>
</div>
Upvotes: 2
Reputation: 5884
There's a couple of options, depending on (somewhat) personal preference:
Leave it and see if Google understands
menu defines the value as either Text or URL, so providing either of these should be sufficient. Doing anything else may confuse Google or another parser as the specification is not followed.
Here's an article which shows a URL providing a menu to Google without any schema, so the system does work.
Provide a schema at the destination of the URL
ItemList is the most generic kind of list and allows you to add itemListElements to the list. This doesn't specify that the list is a menu, but the menu property that the URL has been provided for should be sufficient.
Alternatively, Offer allows you to specify name, description and price which satisfies your requirements. Product doesn't allow you to specify price, so Offer is preferable here. As itemListElement can be a Thing, you can combine Offers in an ItemList.
Upvotes: 2