4

schema.org features a schema for a restaurant:

Thing > Organization > LocalBusiness > FoodEstablishment > Restaurant

One of its fields is a menu:

Property: menu

Expected type: URL or Text

Description: Either the actual menu or a URL of the menu.

The menu item itself is not structured - it has no inner fields like courses or drinks, only a URL/Text attribute.

Image of Schema, thing property menu

  • How should I semanticize the content of a menu like courses and drinks?
  • Should I use the Product class for them?
3

Schema.org has release a new Restaurant Menu Markup

That is really good news!

If you've been waiting for 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.

So, straight to the point:

How to mark up restaurant menus with Schema.org

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/”
}
],
...

Starting the menu page markup:

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”
},

Marking up sections of the menu:

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”
}
}
]
},

Marking up the menu items:

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”
}
}
]
}
]
},

Putting it all together:

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>
3

You could use Product, but I guess you’d only use its name and description properties.

So why not use Offer directly? You can specify name, description, category, and price.

  • The examples in Offer - for example, an offer to sell tickets to an event, to rent the DVD of a movie, to stream a TV show over the internet, to repair a motorcycle, or to loan a book - does not seem like an exact fit to a physical meal. I might be wrong, though. – Adam Matan Dec 14 '14 at 12:24
  • @AdamMatan: You are quoting only examples, but the definition of Offer is: "An offer to transfer some rights to an item or to provide a service" -- which clearly matches, I think. And anyway, if you are using Product, you would have to use Offer too if you want to specify a price (a Product can’t have a price without Offer). – unor Dec 14 '14 at 12:28
2

Perhaps http://schema.org/ItemList would be a better fit. But I'm not sure how it will actually help search engine to parse a menu in a better way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.