// FREE TOOL · RECIPE SCHEMA GENERATOR

Recipe schema generator

Paste a recipe; get Recipe JSON-LD with the steps as HowToStep objects, the times in real ISO 8601 — and a warning every time two properties contradict each other, which on a recipe is most of the ways it goes wrong.

FreeInstantNo signupNothing uploaded
Recipe · generator
The dish

Required. A photo of the finished dish, crawlable and indexable.

Extra terms only — a keyword that repeats the course or the cuisine is the one thing Google says not to put here.

Times

Write it any way you like: 10 min, 1h30, 1:30, 90, PT10M.

Google's rule: always use this together with prep time.

Give this, or give both of the other two.

Servings and nutrition

Just the number of servings. Other units can follow, but the number comes first.

Only meaningful with a serving count — the two are tied together by Google's own wording.

Ingredients and method

Only what is needed to make the dish. No definitions, no shopping advice.

Each line becomes a HowToStep. Leave out "Step 1", "Directions" and "Watch the video".

Errors and warnings
    JSON-LD — paste into the recipe page
    
                
    Visible HTML — the recipe card, same values
    
                

    Everything runs in this page. No recipe, photo URL or ingredient list leaves your browser.

    How to generate recipe schema

    Recipe has more properties that constrain each other than any other common type. The generator writes the markup and the card from one set of values, and reports every contradiction it can see.

    1. Name the dish and add a photo. Those two are required. The photo is of the completed dish, and its URL has to be crawlable — Google suggests several aspect ratios of the same shot.
    2. Give the times in a matching pair. Either a total time, or a prep time and a cook time together. Type them however you think of them; the output is ISO 8601 either way.
    3. Tie calories to a serving count. Calories are per serving, so a calorie figure without a number of servings is incomplete. The generator treats that as an error, because Google states the requirement in one sentence.
    4. Write ingredients and method as lines. One ingredient per line, one step per line. Each step becomes a HowToStep, which Google recommends over a block of prose it has to split up itself.
    5. Paste both outputs. The JSON-LD goes in the recipe page. The card carries the same ingredients and the same steps — which matters here more than anywhere, because those are the strings Google shows.

    The three time properties, and which pairs are legal

    A recipe schema generator turns a recipe into Recipe JSON-LD — the structured data Google reads for ingredients, method, times and nutrition. Only two properties are required, name and image. Everything interesting happens among the optional ones, because several of them are only valid in company.

    On cookTime, Google's documentation says: always use in combination with prepTime. On prepTime: always use in combination with cookTime. On totalTime: use totalTime or a combination of both cookTime and prepTime. So there are exactly two legal shapes, and one common illegal one:

    What you wroteVerdict
    totalTime aloneFine
    prepTime + cookTime (with or without totalTime)Fine
    cookTime alone — the "45 minutes in the oven" recipeBroken. The rule names it.
    No times at allValid, but the time badge on the result has nothing to show.

    All three take ISO 8601 durations — PT1H30M, not 1.5 hours. This form accepts whatever is in your head (10 min, 1h30, 1:30, 90, or the ISO string) and emits the ISO form.

    One thing that is not a Google rule, stated plainly because plenty of advice claims otherwise: totalTime does not have to equal prepTime plus cookTime. Resting, marinating and chilling are real. This tool still warns when the total is smaller than the sum, because that is arithmetic, not policy — and it is usually a typo.

    Calories and servings are one fact, not two

    Google's line on nutrition is short enough to quote: if nutrition.calories is defined, recipeYield must be defined with the number of servings. And on recipeYield: specify the number of servings with just a number; other units may be added as additional yields.

    The reason is that a calorie count is meaningless without knowing what it counts. "calories": "640 calories" on a tray bake is either a light lunch or a family dinner depending on a number that is missing from the markup. This generator makes the missing serving count an error rather than a warning, because the property is not merely incomplete without it — Google says it is required.

    Two shapes that work:

    "recipeYield": "2"
          "nutrition": { "@type": "NutritionInformation", "calories": "640 calories" }
          
          "recipeYield": ["6", "24 cookies"]     // servings first, then the other unit

    And a matching discipline for keywords: they are for extra terms — a season, a holiday, a descriptor — not for repeating what other properties already say. Google's own not-recommended example is "dessert, American", because dessert belongs in recipeCategory and American in recipeCuisine. This form flags a keyword that duplicates either.

    Steps: HowToStep, and nothing that is not the step

    There are three ways to set recipeInstructions, and they are not equal. A single block of text makes Google split the prose into steps itself, guessing where one ends — it says so, and it recommends against relying on that. HowToStep objects say unambiguously where each step starts. HowToSection groups steps when a recipe genuinely has parts (dough, filling, glaze).

    This generator writes one HowToStep per line, and enforces the instruction that comes with it: include only text on how to make the dish and don't include other text such as "Directions", "Watch the video", "Step 1". If a line starts with any of those, it is flagged — the numbering belongs to the markup, not to the sentence.

    The same restraint applies to ingredients: only the text needed to make the dish. A line that explains what tonnarelli is, or where to buy the pecorino, is page content, not an ingredient. Both lists become the visible card as well as the markup, from the same array, so what a reader sees and what Google parses are the same strings — which is the point of the second output, and the same rule behind the FAQ schema generator.

    The two properties recipes usually want next

    A recipe page normally grows two more things, and both have rules that live elsewhere.

    Ratings. aggregateRating is a recommended property of Recipe, and it follows the review snippet guidelines in full: at least one of ratingCount or reviewCount, no averages copied from other sites, no undisclosed incentivized reviews, and — if the recipe carries a single review — a reviewer name that is a real name. Google adds one line specific to recipes: for a single review, the reviewer must be a valid person or organization, and "50% off ingredients" is not one. The review schema generator checks all of that.

    A video. video takes a full VideoObject, with the same required properties any video has: a unique title, a thumbnail at a stable URL, and an upload date that ideally carries its timezone. A recipe video marked up with a contentUrl pointing at the recipe page instead of the video file is the most common failure, and the video schema generator refuses to write it.

    // FAQ

    What is a recipe schema generator?

    A recipe schema generator turns a recipe into Recipe JSON-LD — the structured data Google reads for ingredients, method, times and nutrition. This one writes the steps as HowToStep objects, converts the times to ISO 8601, and reports the places where two properties contradict each other.

    What is required in Recipe structured data?

    Two properties: name and image, where the image is a photo of the completed dish. Ingredients, method, times, yield, nutrition, category, cuisine, author and ratings are all recommended — valuable, but not what decides whether the markup is valid.

    Can I use cookTime without prepTime?

    No. Google's documentation says on both properties that they should always be used in combination with each other. If you only know one number, put it in totalTime instead — totalTime on its own is one of the two accepted shapes.

    Does totalTime have to equal prepTime plus cookTime?

    No, and no Google rule says it does. Resting, chilling, proving and marinating are all real time that belongs in the total but in neither of the other two. This generator warns when the total is smaller than the sum, because that direction is arithmetically impossible and usually means a typo.

    Why does the generator refuse calories without a serving count?

    Because Google requires it: if nutrition.calories is defined, recipeYield must be defined with the number of servings. A calorie figure with no idea how many portions it describes is not information, and the documentation treats the pair as one fact.

    Should recipe instructions be one block of text or separate steps?

    Separate steps, as HowToStep objects. Given a single block, Google tries to split it into steps itself and to strip out section names and step numbers — it recommends specifying steps unambiguously instead. Use HowToSection only when the recipe genuinely has parts.

    Why can't I write "Step 1" in an instruction?

    Google names that exact case: include only text on how to make the dish, and leave out other text such as "Directions", "Watch the video" and "Step 1". The step number comes from the position in the list, so repeating it inside the text is noise that can end up in the rich result.

    clize seo check — free for your own domain

    Which of your recipes does Google actually have?

    Checking your own domain costs nothing: every page with its live HTTP status and index verdict, impressions and average position against the previous window, and traffic by source with AI engines counted separately. One command, from inside your agent.

    $ npm i -g @clize/clize && clize install
    $ clize seo check --domain yourdomain.com
    [ Agent SEO by Clize → ]