Skip to content
Instant · runs in your browser

Schema Markup Generator for 9 Google-Documented Types

Every Google-supported schema type, valid JSON-LD, no invented properties.

Schema markup generator output has to clear 2 separate bars, and most people only check the first. Bar one is syntactic validity: parseable JSON-LD with real schema.org property names. Almost anything passes. Bar 2 is rich result eligibility, a much narrower gate with rules about which types Google still rewards, which properties are mandatory, and whether the values match what a visitor can see on the page. A block can sail through every validator and never produce a single enhanced listing. This tool covers 9 types and tells you which bar you cleared.

Switch type to see the fields that type uses.

Leave blank unless you know you need it. If you type something Google does not recognise, we flag it rather than putting a made-up type in your markup.

Use the questions and answers exactly as they appear on the page. Google ignores schema that promises answers the visitor cannot see.

Full links starting with https://, not /photos/loaf.jpg. Google likes having the same photo in wide, standard and square crops.

A bio page on your own site works better here than a social profile.

Year first, then month, then day: 2024-03-14.

Same format: 2024-06-02. Leave blank if it has not changed since publishing.

At least 112 by 112 pixels, and not cropped - Google rejects logos smaller than that.

LinkedIn, X, Instagram, Wikipedia, Crunchbase - anywhere official that represents the same organisation. This is how Google connects the profiles to you.

Start with + and the dialling code, e.g. +1 for the US, +44 for the UK.

The full name is fine. A postal abbreviation like NY works too.

Latitude then longitude, separated by a comma. Right-click your pin in Google Maps and the first line of the menu is exactly this.

Two-letter days (Mo Tu We Th Fr Sa Su), a range with a hyphen, then the times on a 24-hour clock.

Just the number - no currency symbol. Set the currency below.

Start with the type, then fill the form: schema generators and HowTo

9 types sit behind the switcher, and choosing wrong is the most expensive mistake available here:

  • Article - writing with an author and a date. Refine with BlogPosting or NewsArticle.
  • FAQPage - several questions and answers you wrote yourself, on one page.
  • HowTo - an ordered set of steps for a task.
  • LocalBusiness - a place a customer can physically visit.
  • Organization - the brand behind the site.
  • QAPage - one question with competing answers submitted by other people.
  • Review - one review, of one thing, by one named author.
  • Product - a thing with a price, availability, and possibly a rating.
  • BreadcrumbList - the trail from the homepage to the current page.

Most pages carry 2 or 3 at once. A blog post gets Article plus BreadcrumbList, the homepage gets Organization, a product page gets Product plus BreadcrumbList. Separate script tags, no conflict.

The 33 fields and which markup type reads which

One superset, not 9 separate forms. Each type consumes the subset it needs and ignores the rest. After you generate, the Fields this type uses panel lists what was consumed - if a field isn't there, your value was discarded. The groups:

  • Identity - schema type, more specific type, name/headline, page URL, description, image URLs.
  • Items - the repeatable textarea. Its meaning changes with the type.
  • Authorship - author name, author URL, published date, modified date, publisher name, logo URL.
  • Place and entity - phone, email, street address, city, region, postal code, country, coordinates, price range, opening hours, sameAs profiles.
  • Commerce - brand, SKU, price, currency, availability.
  • Rating - rating value, review count, best rating, review body.

Blank fields never reach the output. There is no "author": null and no "description": "". An empty value is dropped, and so is any nested object left holding nothing but its @type - an author block with no name doesn't ship as an empty Person, it just doesn't exist.

The items box does most of the work. One line per item, left | right. Tab-separated spreadsheet pastes work too, as do Q: / A: prefixed lines on alternating rows. Leading list markers (1., -, *, •) are stripped. The 2 halves mean different things per type:

  • FAQPage - question | answer.
  • HowTo - step name | step text. A line with no pipe becomes a step with text and no name.
  • BreadcrumbList - page name | url. Every crumb except the last needs a URL.
  • QAPage - the first line is the one question; everything after it becomes an answer.

A worked example

Article, subtype BlogPosting, headline "Rebuilding a dead sourdough starter", author Jane Rivera with a bio page, publisher Example Media, published 2024-03-14, modified 2024-06-02:

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Rebuilding a dead sourdough starter",
  "image": [
    "https://example.com/img/starter-16x9.jpg",
    "https://example.com/img/starter-1x1.jpg"
  ],
  "datePublished": "2024-03-14",
  "dateModified": "2024-06-02",
  "author": {
    "@type": "Person",
    "name": "Jane Rivera",
    "url": "https://example.com/about/jane-rivera"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Example Media",
    "logo": { "@type": "ImageObject", "url": "https://example.com/logo.png" }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://example.com/guide/sourdough-starter"
  }
}

2 images, so image is an array. One image would be a bare string. Google accepts either.

Guardrails that stop bad output leaving the tool

Several rules are enforced quietly, and they explain why the output is shorter than what most generators produce:

  • No invented types. The "more specific type" field is checked against a whitelist per root type - the LocalBusiness list alone runs to eighty names. Type Bakery and you get Bakery. Type Bakeries and you get a notice plus a fallback to the base type. A @type that doesn't exist on schema.org makes the whole node meaningless, so nothing unrecognized is emitted.
  • No properties Google doesn't document. Only what Google's reference lists as required or recommended for that type. Padding a block with extra vocabulary doesn't improve eligibility.
  • Headlines truncate at 110 characters, Google's documented limit, with a notice when it happens.
  • Dates are checked against ISO 8601. March 14, 2024 is flagged; 2024-03-14 and 2024-03-14T09:00:00+01:00 pass.
  • Absolute URLs only. A relative /logo.png raises a notice, because a relative URL in JSON-LD resolves against the document base and breaks the moment the block is syndicated.

Validation warns; it never refuses to render.

Types Google no longer rewards

three of the nine types are worth generating only with clear eyes:

  • FAQPage - since August 2023, Google shows FAQ rich results only for well-known government and health sites. If you are neither, the markup is valid and still parsed, but it will not add anything to your listing.
  • HowTo - Google retired HowTo rich results in Search in 2023. The vocabulary is still real schema.org and still read by non-Google consumers; it will not change how your page looks in Google.
  • QAPage - only legitimate on pages where visitors can submit competing answers. Using it for your own FAQ is a structured data violation, not a clever workaround for the FAQ restriction.

Ratings work the same way. Google ignores self-serving reviews - a review or aggregate rating you publish about your own business or product, on your own site. Marking it up doesn't make it count.

Why the generated markup escapes angle brackets

The output escapes <, >, and & as \u003c, \u003e, and \u0026. Still valid JSON, and every parser decodes it back. The reason is placement: an HTML parser ends a <script> element at the first literal </script> it sees, even inside a JSON string. A review body quoting some HTML would otherwise cut your block in half and dump the rest as visible text. Escaping makes that impossible.

The rest of placement is short. <head> or <body>, Google reads both. Organization goes on exactly one URL per site, normally the homepage. A page under 2 breadcrumb trails gets 2 BreadcrumbList blocks, not one merged.

Mistakes that pass validation and still fail

  • Values that aren't on the page. Every marked-up question, answer, step, price, and date must be visible to a human reading the rendered page. Schema-only content is the most common cause of a manual action.
  • Prices that drift. Product price, currency, and availability must match the page at crawl time. A stale price is worse than none, and a price without a 3-letter priceCurrency is invalid for merchant listings anyway.
  • A rating without a count. aggregateRating needs both a value and a review count; supply one and the node is dropped rather than shipped broken.
  • Copying a competitor's block. Their publisher and logo end up on your page, quietly attributing your content to them.

Run the finished block through Google's Rich Results Test for eligibility and the schema.org validator for vocabulary. They answer different questions. If structured data is one item on a much longer content list, BlazeHive automates SEO content end to end, schema included.

Frequently Asked Questions

Do I need a separate script tag for each type?

No, but it's simpler. Multiple nodes can share one tag via a @graph array. Separate tags are easier to debug: a syntax error takes down one block instead of all of them.

Does more schema markup improve rankings?

Not directly. It changes how a result is presented and helps search engines resolve entities, but it isn't a ranking factor. That's why marking up types that no longer produce enhancements changes nothing about your traffic.

What happens if I leave most fields empty?

You get a valid but bare node plus a list of what Google requires and recommends. Output is never blocked, so it's a fast way to see the shape of a type before gathering values.

Why is my JSON shorter than what other generators produce?

Empty values and objects holding nothing but a @type are pruned, and only Google-documented properties are included. A short block that matches the page beats a long one padded with vocabulary nothing reads.

Related free tools

All tools →