Restaurant Schema Markup: Structured Data Explained
There is a version of your menu that no customer will ever see, and it might be the most important one you publish. It is called structured data, or schema markup, and it is how your menu page introduces itself to machines: search engines, map apps, and increasingly the AI assistants people ask for dinner recommendations.
This article explains it for restaurant owners, not developers. No code needs to be written by you at the end of it. But you should understand what the code says on your behalf, because it is quietly part of how your menu gets onto Google and stays trusted there.
The problem structured data solves
When Google reads a normal web page, it sees text and has to guess what the text means. On a menu page, “Margherita 14” might be a pizza and a price, or a street address, or a wine and a table number. Humans resolve this instantly from context. Machines guess, and guesses are fragile.
Structured data removes the guessing. It is a block of labeled facts, invisible on the page, written in a vocabulary called schema.org that every major search engine agreed on. Instead of “figure it out,” your page says: this is a Restaurant, its cuisine is Italian, here is its Menu, the menu has a section called Pizza, the section has an item called Margherita, the item’s price is $14 and it is vegetarian.
The format this usually takes is called JSON-LD, which is just the labeled-facts block wrapped in a script tag in the page’s code. You never see it in the browser. Crawlers read it every visit.
What it looks like (a real example)
Here is a trimmed but genuine example of what a menu page’s structured data says. You do not need to read code; read the labels.
{
"@context": "https://schema.org",
"@type": "Restaurant",
"name": "Rosa's Kitchen",
"servesCuisine": "Italian",
"telephone": "+1-555-014-2233",
"address": {
"@type": "PostalAddress",
"streetAddress": "412 Grand Ave",
"addressLocality": "St. Paul",
"addressRegion": "MN",
"postalCode": "55102"
},
"hasMenu": {
"@type": "Menu",
"hasMenuSection": [
{
"@type": "MenuSection",
"name": "Pizza",
"hasMenuItem": [
{
"@type": "MenuItem",
"name": "Margherita",
"description": "San Marzano tomato, fior di latte, basil",
"offers": {
"@type": "Offer",
"price": "14.00",
"priceCurrency": "USD"
},
"suitableForDiet": "https://schema.org/VegetarianDiet"
}
]
}
]
}
}Even without knowing code, you can see the structure: every fact is labeled, every price is attached to its item, every item to its section. That is the entire trick. There is nothing more mystical happening.
The vocabulary that matters for restaurants
You will encounter a handful of schema types. Here is the map:
| Schema type | What it describes | Why you care |
|---|---|---|
Restaurant | The business itself: name, address, phone, hours, cuisine | The anchor everything else attaches to; helps confirm your identity across the web |
Menu | A menu belonging to the restaurant | Tells crawlers “this page is the menu,” not a blog post about food |
MenuSection | A group like Starters or Desserts | Preserves your menu’s organization as data |
MenuItem | One dish, with name and description | Makes individual dishes findable and quotable |
Offer | The price and currency of an item | The part that lets machines state your prices correctly |
suitableForDiet | Vegetarian, vegan, gluten-free and similar flags | Feeds dietary filtering, a growing slice of searches |
OpeningHoursSpecification | Your hours as data | Backs up the hours on your listings |
What you actually get out of it
Straight answers, no overselling:
- Correctness where it counts. Structured data is a strong hint, and it makes your menu legible as data rather than leaving crawlers to parse a PDF or, worse, a photo. When machines quote your restaurant, you want them quoting labeled facts you published.
- Consistency reinforcement. Search engines cross-check your website, your Google Business Profile menu, and other listings. Machine-readable agreement between them builds trust in all of them. This is the same consistency principle that runs through all local SEO for restaurants.
- A seat at the AI table. Assistants answering “vegetarian pizza near me” work from whatever structured information they can get. Pages that describe themselves as data are simply easier to answer from than pages that are pictures of text.
What it will not do: no guaranteed rich results, no rankings jump next Tuesday. It is plumbing. Plumbing does not sell dinner, but everything that sells dinner runs through it.
How to get it without writing code
Three routes, by situation:
1. Use a menu platform that generates it. This is the sane default. VisibleMenus builds Restaurant and Menu structured data into every hosted menu page automatically, generated from the same menu data that powers your QR menu and your Google updates. When you change a price, the JSON-LD changes with it, which is the part hand-written markup always gets wrong: it is accurate on day one and stale by month three, and stale structured data confidently tells machines the wrong price.
2. Hand it to your web person. If you have a website with a menu page, send them this article. The work is small: generate the JSON-LD from the menu content and keep the two in sync. That second clause is the real requirement. Markup that drifts from the visible menu is worse than none.
3. Skip your site, keep a hosted menu page. If your “website” is a Facebook page and a prayer, you do not need to solve structured data on a site you do not have. A hosted menu page that includes it, linked from your Google and Apple listings, covers the machine-readability job completely.
There is a pleasant side effect worth knowing about. A hosted QR menu page is a real web page, which means it gets crawled and indexed like one. Your menu becomes findable through search directly, not just scannable at the table. More on that dual life of QR menu pages in the QR code menu guide.
How to check what you have (two minutes, no skills)
- Open your menu page in a browser.
- View the page source (right-click, “View Page Source”).
- Search the text for
application/ld+jsonor justschema.org. - If it is there, skim the block. Can you see your restaurant name, items, and prices? Do the prices match reality?
- For a proper report, paste your menu page URL into Google’s free Rich Results Test at search.google.com/test/rich-results and see what it detects.
Three myths worth retiring
“Schema is an SEO trick that Google penalizes now.” No. Deceptive markup, claiming to be something you are not, gets penalized. Accurate markup describing a real menu is exactly what the vocabulary exists for, and Google publishes documentation encouraging it.
“My web guy added it in 2022, so I’m covered.” Markup generated once is a snapshot. If your menu has changed since, your structured data is now confidently wrong, which is worse than absent. The only markup worth having is markup generated from your live menu on every change.
“It’s pointless because I can’t see any difference.” You cannot see the difference by looking, which is the nature of plumbing. The observable version is indirect: machines that describe your restaurant, from search snippets to AI assistants, describe it correctly. The failure case, being described wrongly or not at all, is also invisible until you go checking. So go check.
If you find nothing, or you find prices from two menus ago, you know your next move. And if the phrase “prices from two menus ago” hit close to home, the damage runs well past the markup: an outdated menu on Google costs real customers, and the fix for both problems is the same single source of truth.
Structured data is the least glamorous thing your menu does. It is also the difference between machines guessing about your restaurant and machines quoting it correctly. Make sure someone, or something, is writing it for you.