Schema Markup Validator
Checks JSON-LD in three layers and says which authority each finding comes from, because valid schema.org and eligible for a rich result are different things.
Parses yes
Nodes with a @type 2
Types this checks Product
Types it does not Offer
Errors 1
Warnings 7
Findings
error, schema.org datePublished is "14/03/2026", which is not ISO 8601. Write 2026-03-14, or 2026-03-14T09:30:00+00:00 when the time matters.
warning, Google image is "/img/pro.jpg", which is not an absolute URL. A leading slash is not enough: structured data gets read out of the page's context, so there is nothing for it to resolve against.
warning, Google price at offers is a number. Google asks for a string, because 9.90 as a number loses the trailing zero and 1,299 with a separator is not a number at all.
warning, Google Product has no aggregateRating, which Google recommends. Only mark up ratings that are visible on the page. Invisible review markup is the most common manual action in this area.
warning, Google Product has no brand, which Google recommends.
warning, Google Product has no description, which Google recommends.
warning, Google Product has no review, which Google recommends.
warning, Google Product has no sku, which Google recommends.
The errors are the ones that stop a rich result. Each says which
authority it comes from: a schema.org error means the data is malformed,
and a Google error means the rich result needs something the data does
not have.
Offer is a type this tool has no rules for, so it was parsed and not
checked. That is not a verdict either way: schema.org has hundreds of
types and only a dozen or so produce rich results.
Mark up only what a visitor can see. Invisible review markup, prices
that differ from the page, and FAQ content that is not on the page are
the usual causes of a manual action in this area, and a manual action
costs every rich result on the site rather than the one.
This is a static check of one block. Google's Rich Results Test fetches
the live page, runs the JavaScript and tells you which rich result it is
eligible for, which is the thing to confirm with before you ship. Use
this to fix the obvious problems first, because a broken block fails
silently and a fetch tells you nothing about why.
JSON-LD in a script tag is the format to use. Microdata and RDFa are
still read, and they tangle the data into the markup, so a template
change breaks them in ways nobody notices.
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Structured data has three ways to be wrong, and a validator that does not say which one you are looking at is not much help.
The JSON does not parse. A trailing comma, or a smart quote from a word processor. The whole block is ignored in silence: no error anywhere, no rich result, and nothing in the page source that looks wrong.
The vocabulary is wrong. @context is not schema.org, or @type is Blogpost
rather than BlogPosting.
It is valid schema.org and not eligible for a rich result. This is the common case.
schema.org is permissive: a Product with nothing but a name is valid. Google’s
requirements are stricter, and a Product with no offer, review or rating will not
produce a rich result however valid it is.
So every finding here says which authority it came from and what it costs.
How to use
- Paste the JSON-LD, or the whole
<script type="application/ld+json">block. - Fix the errors first: those are the ones that stop a rich result.
- Then confirm with Google’s Rich Results Test, which fetches the live page.
Example
The default sample has three real problems in it:
Parses yes
Nodes with a @type 2
Types this checks Product
Types it does not Offer
Errors 1
Warnings 6
Findings
error, schema.org datePublished is "14/03/2026", which is not ISO 8601. Write 2026-03-14, or 2026-03-14T09:30:00+00:00 when the time matters.
warning, Google price at offers is a number. Google asks for a string, because 9.90 as a number loses the trailing zero and 1,299 with a separator is not a number at all.
warning, Google image is "/img/pro.jpg", which is not an absolute URL. A leading slash is not enough: structured data gets read out of the page's context, so there is nothing for it to resolve against.
Note the Types it does not line. Offer has no rules here, so it was parsed and not
checked, and saying so is more useful than a clean report that implies it passed.
Pitfalls
A relative URL is not enough, even with a leading slash. Structured data gets read
out of the page’s context, so /img/pro.jpg has nothing to resolve against. Absolute
https, every time.
Price is a string. 9.90 as a number loses its trailing zero, and 1,299 with a
separator is not a number at all. Google’s documentation asks for a string with
priceCurrency beside it.
Author is an object. "author": "Liton" is valid schema.org and will not produce the
author in a rich result. It needs to be a Person or an Organization with a name.
Dates are ISO 8601 with an offset. 14/03/2026 is ambiguous between two continents
and is not a date to a parser. 2026-03-14 for a day, 2026-03-14T09:30:00+00:00 when
the time matters.
Durations are ISO 8601 too. PT30M, not “30 minutes”. This catches out every recipe
and video markup written by hand.
Only mark up what a visitor can see. Invisible review markup, a price that differs from the page, FAQ content that is not on the page: these are the usual causes of a manual action, and a manual action costs every rich result on the site rather than the one.
Valid does not mean eligible. Eligibility also needs the page indexed, the markup matching the visible content, and Google choosing to show the result. No validator can tell you the last one.
Google retires rich results. HowTo went in 2023 and FAQ results were cut back to a
narrow set of sites. Markup is still worth having for clarity and for other consumers; the
rich result is not a promise.
Compatibility
Everything runs in the browser: nothing is uploaded, nothing is stored, and no page is fetched.
Twelve types have rules here: Article with its NewsArticle and BlogPosting aliases, Product, LocalBusiness and its subtypes, Organization, FAQPage, BreadcrumbList, Event, Recipe, JobPosting, WebSite, Person, VideoObject and HowTo. Anything else is parsed, counted and listed as unchecked. schema.org has hundreds of types and only a dozen or so produce rich results, so that is where the rules are.
Required and recommended follow Google’s structured data documentation rather than
schema.org’s own cardinality, which is almost entirely optional. Where a message says
“schema.org”, it is about the shape of the value: a date that is not a date, a duration
that is not a duration, a missing @context.
Recommended properties are only checked on the top-level node. A Person used as an
author needs a name and nothing else, and asking it for a jobTitle would bury the
findings that matter.
JSON-LD in a script tag is the format to use. Microdata and RDFa are still read and they tangle the data into the markup, so a template change breaks them in ways nobody notices.
Frequently asked questions
Is this the same as Google’s Rich Results Test?
What about the Schema Markup Validator at validator.schema.org?
Why is my valid markup not showing a rich result?
Should I put the markup in the head or the body?
Can I have more than one block on a page?
@graph with several nodes is the tidier
form when they reference each other.