← Back to Structured Data Drift Check
Google's Search Central documentation for the FAQPage and
HowTo structured-data types both say the same thing in
substance: the markup has to reflect content that is actually on the page
and visible to a visitor, not text that exists only inside a
<script type="application/ld+json"> block. A page that
markets up a question and answer nobody can read is, per that guidance, not
eligible for the rich result the markup is meant to earn — and Google's own
spam policies treat structured data describing hidden or absent content as
a form of misleading markup, not a harmless inaccuracy. This page describes
the rule rather than quoting Google's current wording verbatim, because
that wording can change without notice; read the current guidance on
developers.google.com for the authoritative text.
Nothing about how a page is normally built keeps its visible copy and its JSON-LD in sync. A marketer edits an FAQ answer on the page and never touches the schema. A developer writes the schema once at launch, off the copy as it existed that day, and the copy keeps evolving underneath it. A templating system interpolates the same variable into both places today and a refactor six months later interpolates it into only one. In every case the drift is invisible to a human reader, because nobody reads raw JSON-LD next to rendered copy side by side — which is exactly the comparison this tool automates.
Google's written policy names two structured-data types. The underlying
reason it exists — markup should describe what is actually on the page —
is not specific to either one. An AI system that reads a page's JSON-LD to
summarize it, answer a question about it, or decide what to tell a user
about a product, business, or review has no equivalent published rule
requiring the markup to match what a human visitor sees; it can simply
treat the JSON-LD as a structured, pre-parsed statement of fact and repeat
it. A Product description, a LocalBusiness
address claim in prose, a fabricated-sounding Review body, or
an Article headline that no longer matches the page's own
<h1> can mislead exactly the same way a stale FAQ answer
can — this tool checks all six because the risk is not limited to the two
types Google has written a rule about.
| Type | Fields checked |
|---|---|
FAQPage | mainEntity[].name (question), mainEntity[].acceptedAnswer.text (answer) |
HowTo | name, description, step[].name, step[].text |
Article / BlogPosting / NewsArticle | headline, description |
Product | name, description |
LocalBusiness / Organization (and common subtypes) | name, description |
Review | reviewBody, author.name |
Deliberately excluded: numeric and URL fields (ratingValue,
priceCurrency, image, url, dates,
and so on). Those aren't prose a visitor reads and confirms by eye the way
an FAQ answer or a headline is, and a false-positive divergence report on a
formatting difference in a number would train a reader to ignore real
findings — the same failure mode this portfolio's other checkers avoid by
staying narrow.
Run it against a static build's output directory after every deploy that touches copy or schema:
- name: Check structured data against visible page text
run: |
npm run build
find dist -name '*.html' | xargs node ventures/structured-data-drift-check/cli.mjs check
The command exits non-zero if any claim on any page diverges from that
page's own visible text. Add --strict to also fail on a
malformed application/ld+json block, which is a different bug
this tool notices but does not fail on by default.
Google's Search Central documentation for both the FAQPage and HowTo structured data types states that the markup must reflect the main content of the page, and that content used only in structured data and not shown to users is not eligible for the rich result. This tool does not quote the live page text verbatim since that text can change without notice; read the current FAQPage and HowTo structured data guidelines on developers.google.com for the exact current wording, and treat this as the sourced, dated pointer to go read it rather than a substitute for doing so.
A search engine's rich-result eligibility check is one consumer of JSON-LD. An AI system summarizing or answering questions about a page is another, and it has no equivalent published policy requiring the markup to match what a human sees -- it can simply read the JSON-LD as a structured, pre-parsed statement of what the page says and repeat it. A Product, Review, or Organization block that drifted from the page's actual copy is exactly as capable of misleading a reader that way as a FAQPage block is, even though Google's written rule names only two of the six types this tool checks.
It doesn't, directly -- this tool checks one page's JSON-LD against that same page's own visible text, not two point-in-time snapshots against each other. The shared idea with this portfolio's other checkers is the same deterministic, no-network, no-verdict shape: read exactly what is already present, compare two specific things character by character, and report precisely where they part ways rather than issuing an opinion.