A recipe page describes one dish and how to make it. The markup is Recipe, and the rewards are the richest of the everyday results: the recipe snippet with photo, rating and cooking time, and the recipe carousel at the top of food searches.

What is required — four properties, and two of them are shapes

  • name — the dish.
  • image — absolute URLs, and genuinely of the finished dish. Recipe surfaces are image-first; provide 16×9, 4×3 and 1×1 versions if you can.
  • recipeIngredient — a list, one ingredient per entry ("200g paneer, cubed"). One string containing the whole shopping list is valid JSON and useless data — the parser cannot tell your ingredients apart.
  • recipeInstructions — a list of HowToStep objects, one step each. The same rule: a single blob of prose robs Google of the structure the snippet is built from.

What upgrades the snippet

  • prepTime, cookTime, totalTime — ISO 8601 durations (PT20M, PT1H30M), which is the form the snippet reads. "45 minutes" as text is invisible to it. Declare totalTime even when the parts are declared; it is the number shown.
  • recipeYield — how many it serves.
  • nutrition — at minimum calories, which can appear on the snippet.
  • aggregateRating — with real, visible reviews behind it.
  • author, datePublished, description — the article-side basics.
  • video — a VideoObject of the method, which makes the recipe eligible for video-enhanced placements.

An example

{
  "@context": "https://schema.org",
  "@type": "Recipe",
  "name": "Paneer Butter Masala",
  "image": ["https://example.com/img/pbm-16x9.jpg"],
  "author": {"@type": "Person", "name": "E. Cook"},
  "datePublished": "2026-06-14",
  "description": "Restaurant-style paneer in a tomato-cashew gravy.",
  "prepTime": "PT20M",
  "cookTime": "PT30M",
  "totalTime": "PT50M",
  "recipeYield": "4 servings",
  "recipeIngredient": ["200g paneer, cubed",
                       "3 tomatoes, puréed",
                       "12 cashews, soaked"],
  "recipeInstructions": [
    {"@type": "HowToStep", "text": "Blend the tomatoes and cashews."},
    {"@type": "HowToStep", "text": "Simmer the gravy for 15 minutes."},
    {"@type": "HowToStep", "text": "Add the paneer and finish with cream."}
  ],
  "nutrition": {"@type": "NutritionInformation", "calories": "420 kcal"}
}

The mistakes that cost the carousel

Ingredients or instructions as one blob. The requirement is not that the words exist but that the structure does — this is the single commonest recipe markup failure.

Times as prose. "45 minutes" is not a duration; PT45M is.

A rating with no reviews on the page. Self-declared stars are the recipe world's manual-action magnet, same as products.

Checking your page

Validate the block with the structured data validator — shape errors show up immediately — then run the complete page audit, which also confirms the images resolve and the page is indexable enough for the carousel to consider it.