Skip to main content

schema.org/Recipe

When a recipe app takes a URL and returns a title, an ingredient list, a cook time and a photo, schema.org/Recipe is usually the source. It is the most widely deployed structured description of food on the web, adopted at scale because the major search engines consume it.

This page is a reference for the type itself: its place in the hierarchy, every property it defines, the inherited ones that appear on recipes, and what the markup looks like in practice. For what Microdata, RDFa and JSON-LD are as syntaxes, and how schema.org came to exist at all, start with the introduction. For the older, HTML-class-based approach to the same problem, see hRecipe.

About this reference​

Canonical URLhttps://schema.org/Recipe
HierarchyThing → CreativeWork → HowTo → Recipe
Published byschema.org — Bing, Google, Yahoo!, Yandex
Typical syntaxesJSON-LD (dominant), Microdata, RDFa
Reflects the vocabulary as ofschema.org version 30.0

The property lists below were built from the schema.org vocabulary dump rather than transcribed by hand, so the ranges are the ranges the vocabulary actually declares — which is not always what the tutorials say.


Where Recipe sits​

A recipe, in schema.org's model, is a kind of instruction set that happens to produce food. The full chain is:

LevelTypeWhat it contributes
1Thingname, description, image, url, identifier, sameAs.
2CreativeWorkAuthorship, dates, licensing, ratings, video, keywords.
3HowToSteps, supplies, tools, durations, yield, estimated cost.
4RecipeThe food-specific narrowing: ingredients, cuisine, nutrition, diet.

That ordering post-dates the types themselves. Recipe is the older type; HowTo arrived later and was slotted in above it. Schema.org's release notes for version 3.3 (14 August 2017) describe adding "a HowTo type, building upon and generalizing the existing Recipe vocabulary" — that release introduced estimatedCost, steps, supply and tool, and generalized recipeYield into yield and cookTime into performTime.

This is why several Recipe properties are formally sub-properties of HowTo ones, and why you will meet near-duplicate pairs:

Recipe propertySub-property ofMeaning of the pair
cookTimeperformTimeTime spent actually doing the thing.
recipeYieldyieldWhat comes out the other end.
recipeIngredientsupplyThings consumed by the process.
recipeInstructionsstepThe ordered procedure.

Both members of each pair are valid. In practice publishers use the recipe* form and consumers should read both.

How it is published​

Two syntaxes carry essentially all Recipe markup in the wild. JSON-LD sits in a <script type="application/ld+json"> block in the document, structurally independent of the visible HTML. Microdata annotates the visible HTML itself with itemscope / itemtype / itemprop attributes. RDFa Lite is legal and almost unused for recipes. All three are described in detail on the JSON-LD, Microdata and RDFa section of the intro page.

JSON-LD decouples the markup from the template: a CMS plugin can emit the block without a theme author touching a single <div>. The trade-off is that the structured data and the human-visible page are separate documents, and the two can differ.


Properties defined on Recipe​

These nine are declared directly on Recipe. Everything else you see on a recipe in the wild is inherited.

PropertyTypeWhat it holds
recipeIngredientItemList, PropertyValue, TextAn ingredient, or an ordered list of them, with quantities. Free text like "2 slices sourdough" is the overwhelming norm.
recipeInstructionsCreativeWork, ItemList, TextThe procedure — a single item, or an ordered list of HowToStep and/or HowToSection items. See the shapes it takes.
recipeYieldQuantitativeValue, TextWhat the recipe produces: "4 servings", "one 9-inch loaf", "12".
cookTimeDurationTime the dish is actually cooking, as an ISO-8601 duration (PT30M).
recipeCategoryTextThe course or role — "appetizer", "entree", "dessert". Uncontrolled vocabulary.
recipeCuisineTextThe culinary tradition — "French", "Ethiopian". Also uncontrolled.
cookingMethodTextHow it is cooked — "Frying", "Steaming". Uncontrolled, and rarely emitted.
nutritionNutritionInformationA structured nutrition block. See nutrition.
suitableForDietRestrictedDiet, DietA dietary restriction the dish satisfies. RestrictedDiet is an enumeration; Diet comes from the health-lifesci extension.

Superseded on Recipe​

PropertyTypeStatus
ingredientsTextSuperseded by recipeIngredient. Defined as a single ingredient. Still emitted by aging templates.

Superseded, in schema.org's model, does not mean removed. ingredients still resolves, still validates, and still shows up in real documents served today. A parser that ignores it will silently lose ingredient lists on older sites.

The RestrictedDiet enumeration​

suitableForDiet is one of the few places Recipe reaches for a controlled vocabulary rather than free text. The members are:

DiabeticDiet, GlutenFreeDiet, HalalDiet, HinduDiet, KosherDiet, LowCalorieDiet, LowFatDiet, LowLactoseDiet, LowSaltDiet, VeganDiet, VegetarianDiet.

Eleven values, expressed as URLs (https://schema.org/VeganDiet). Several restrictions in common use are absent — dairy-free, nut-free, keto, pescatarian. Schema.org's own note on Recipe directs publishers to keywords for dietary detail the enumeration does not cover.


Inherited from HowTo​

These are declared on HowTo and available on every Recipe. Several of them are the general form of a Recipe-specific property; a few have no Recipe-specific counterpart at all and are the only way to express the concept.

PropertyTypeWhat it holds
prepTimeDurationTime to prepare the supplies before the cooking starts. ISO-8601.
totalTimeDurationTotal time, preparation included. ISO-8601.
performTimeDurationThe general form of cookTime — time spent performing the instructions.
yieldQuantitativeValue, TextThe general form of recipeYield.
stepCreativeWork, HowToSection, HowToStep, TextThe general form of recipeInstructions.
supplyHowToSupply, TextSomething consumed by the process — the general form of recipeIngredient.
toolHowToTool, TextSomething used but not consumed: a skillet, a spatula. The nearest thing to equipment.
estimatedCostMonetaryAmount, TextEstimated cost of the supplies.
SupersededTypeStatus
stepsCreativeWork, ItemList, TextSuperseded by step. Introduced in v3.3 and renamed almost immediately — the vocabulary itself notes it was "originally misnamed".

There is no recipeEquipment property. Equipment is expressed with the inherited tool, which the vocabulary distinguishes from supply by consumption: supplies are consumed by the process, tools are not.

The step types​

TypeWhat it holds
HowToStepOne step. Simultaneously a CreativeWork, an ItemList and a ListItem — so it can nest.
HowToSectionA named group of steps, e.g. "For the crust" inside a pie recipe.
HowToSupplyA structured supply, with a requiredQuantity.
HowToToolA structured tool.

Inherited from CreativeWork and Thing​

CreativeWork alone contributes well over a hundred properties, most of which have nothing to do with food. These are the ones that actually appear on recipes.

PropertyFromTypeWhat it holds
nameThingTextThe dish's name. Effectively mandatory in practice.
descriptionThingText, TextObjectThe headnote — the paragraph before the ingredients.
imageThingImageObject, URLA photo of the finished dish.
urlThingURLCanonical URL for the recipe.
sameAsThingURLA URL unambiguously identifying the same thing elsewhere.
authorCreativeWorkPerson, OrganizationWho wrote it.
publisherCreativeWorkPerson, OrganizationWho published it.
datePublishedCreativeWorkDate, DateTimeFirst publication date.
dateModifiedCreativeWorkDate, DateTimeLast revision date.
keywordsCreativeWorkDefinedTerm, Text, URLFree tags. Carries the load suitableForDiet cannot.
aggregateRatingCreativeWorkAggregateRatingAverage star rating plus a count.
reviewCreativeWorkReviewIndividual reviews.
videoCreativeWorkClip, VideoObjectAn embedded how-to video.
inLanguageCreativeWorkLanguage, TextBCP 47 language tag.
licenseCreativeWorkCreativeWork, URLThe licence the recipe is published under. Almost never present.
isBasedOnCreativeWorkCreativeWork, Product, URLAdapted-from: the work this recipe is derived from.
mainEntityOfPageThingCreativeWork, URLSays this recipe is what the page is about.

Nutrition​

nutrition takes a NutritionInformation (Thing → Intangible → StructuredValue → NutritionInformation), which declares twelve properties.

PropertyTypeWhat it holds
servingSizeTextThe serving this block describes.
caloriesEnergyCalorie count.
fatContentMassGrams of fat.
saturatedFatContentMassGrams of saturated fat.
unsaturatedFatContentMassGrams of unsaturated fat.
transFatContentMassGrams of trans fat.
cholesterolContentMassMilligrams of cholesterol.
carbohydrateContentMassGrams of carbohydrate.
fiberContentMassGrams of fibre.
sugarContentMassGrams of sugar.
proteinContentMassGrams of protein.
sodiumContentMassMilligrams of sodium.

Energy and Mass are both quantity types serialised as text with a unit — "240 calories", "9 g". The unit lives inside the string, which means every consumer writes the same small unit-parsing routine.


A grilled cheese, marked up​

The minimum viable Recipe, as JSON-LD:

<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Recipe",
"name": "Grilled Cheese",
"recipeYield": "1 sandwich",
"cookTime": "PT6M",
"recipeIngredient": ["2 slices bread", "2 slices cheddar", "1 tbsp butter"],
"recipeInstructions": [
{ "@type": "HowToStep", "text": "Butter one side of each slice of bread." },
{ "@type": "HowToStep", "text": "Sandwich the cheese between the unbuttered sides." },
{ "@type": "HowToStep", "text": "Griddle over medium heat until golden on both sides." }
]
}
</script>

The same recipe as Microdata, annotating markup a human actually reads:

<div itemscope itemtype="https://schema.org/Recipe">
<h1 itemprop="name">Grilled Cheese</h1>
<p>Makes <span itemprop="recipeYield">1 sandwich</span> in <meta itemprop="cookTime" content="PT6M" />6 minutes.</p>
<ul>
<li itemprop="recipeIngredient">2 slices bread</li>
<li itemprop="recipeIngredient">2 slices cheddar</li>
<li itemprop="recipeIngredient">1 tbsp butter</li>
</ul>
<ol itemprop="recipeInstructions">
<li>Butter one side of each slice of bread.</li>
<li>Sandwich the cheese between the unbuttered sides.</li>
<li>Griddle over medium heat until golden on both sides.</li>
</ol>
</div>

Note the <meta> element in the Microdata version. cookTime takes an ISO-8601 duration and the visible text reads "6 minutes", so the machine value is carried in an empty element next to the human-readable one. JSON-LD does not have this problem because it does not share the DOM with the rendered page.


What the markup looks like in practice​

The vocabulary permits more variation than most publishers exercise, and real documents diverge from the specification in consistent ways. What follows is description of the deployed web, not of the standard.

recipeInstructions arrives in four shapes. Its declared range is Text, ItemList or CreativeWork, and because HowToStep and HowToSection are both subclasses of CreativeWork, a conforming parser has to handle all of: a single string containing the whole method; an array of strings; an array of HowToStep objects; and an array of HowToSection objects each wrapping its own array of steps. All four are valid and all four are common. The single-string case carries no step boundaries, so splitting it is heuristic.

recipeYield is free text in practice. "4 servings", "4-6", "Serves 4", "12 cookies", "1 loaf" and bare "4" all appear. The QuantitativeValue range is available and rarely used, so numeric scaling requires parsing the string.

Durations are frequently malformed. cookTime, prepTime and totalTime take ISO-8601 (PT30M). Production markup also contains "30 min", "PT30", "P30M" (which parses as thirty months), "0:30" and bare "30".

Three descriptive properties are uncontrolled. recipeCategory, recipeCuisine and cookingMethod are plain Text with example values in the documentation and no enumeration, so "dessert", "Dessert", "Desserts" and "Sweets" are four distinct values to an aggregator. suitableForDiet is the one property with a controlled list, and it has eleven members.

Search-engine requirements shape what gets emitted. Google's recipe rich-result documentation lists two required properties — name and image — with everything else recommended. Markup in the wild reflects those incentives: aggregateRating and a hero image are near-universal, and the JSON-LD block and the visible page can carry different values for the same field.

Superseded properties remain in circulation. Supersession in schema.org is advisory, so ingredients and steps are still valid, still resolve, and are still emitted by long-untouched templates. Parsers that drop them lose data on older sites.

Nutrition units are inside the strings. "9 g", "240 calories" — every consumer parses the unit out of the value.


Further reading​

  • schema.org/Recipe — the canonical type page, with live examples in all three syntaxes.
  • schema.org/HowTo — the parent type, and the source of the step, supply, tool and duration vocabulary.
  • schema.org itself, and its release history — every version, with the types and properties each one added, changed or superseded.
  • hRecipe — the microformats recipe vocabulary, released in 2008 and built on HTML class names instead of a parallel document.

Two vocabularies, one dish. schema.org puts the description in a parallel data structure; microformats puts it in the HTML a person is already reading. Both are emitted on the web today, and Buttery reads both.