BlogFindings
Structured data for AI: 70 of 146 markup values were not on the page
Parsed with an HTML parser on 26 August 2026 out of five real pages this scanner captured and stored on 15 July 2026, the four JSON-LD blocks in the set carry 146 distinct human readable text values. 76 of those values appear somewhere in the visible text of the page they sit on. 70 do not. One page contributes 140 of the 146.
So this post tests it. Not on the open web, which this site has no licence to survey, but on the five real documents already frozen in this repository as golden fixtures, captured on 15 July 2026: the Astro homepage, the Gymshark storefront, the MDN HTML reference, the Webflow homepage and the English Wikipedia article on web crawlers. An earlier count established that three of five captured pages carried JSON-LD, holding 102 typed nodes in four blocks. This post asks a different question of the same four blocks. Take every human readable text value in them, and check whether that value appears anywhere in the visible text of the document that publishes it. The answer, on 26 August 2026, is that 76 of 146 do and 70 do not.
In short
- Structured data for AI is a claim about a page, and on these pages the claim often has no page behind it: parsed on 26 August 2026 across five real captures frozen on 15 July 2026, 70 of 146 distinct JSON-LD text values appear nowhere in the visible text of the document that publishes them.
- Google's structured data general guidelines, carrying Last updated 2026-07-10 UTC, state plainly that you should not mark up content that is not visible to readers of the page, and give the example that if the JSON-LD describes a performer, the HTML body must describe that same performer.
- featureList was the property that missed most: 18 of its 19 values across the set are absent from the page text. description missed 15 of 37 and name missed 14 of 52, while reviewBody missed only 1 of 6.
- The concentration matters more than the ratio. The Webflow homepage publishes 140 of the 146 values and 67 of the 70 misses, the Astro and MDN pages publish no JSON-LD at all, and five pages captured on one day is not a sample of the web.
- Lantad does not score this. SCHEMA_REQUIREMENTS in core/src/schema.ts checks that a block parses, carries a type and holds that type's required properties, and no check anywhere in the scanner compares a markup value against the text of the page it sits on.
Flow: Stored capture, 15 July 2026 (2 pages publish none) to 4 JSON-LD blocks; 4 JSON-LD blocks to 102 typed nodes; 102 typed nodes (URLs and dates excluded) to 146 distinct text values; 146 distinct text values to Compared against visible page text; Compared against visible page text (76) to 76 present on the page; Compared against visible page text (70) to 70 absent from the page.
Does structured data for AI need to match the visible page?
Google answers this in two documents that are usually read separately and belong together. The first is the page on AI features, which states that you do not need to create new machine readable files or markup to appear in them and that there is also no special schema.org structured data that you need to add. That sentence has been quoted here before, in the post noting that Google's generative AI guide names five GEO tactics you can ignore, and it is routinely read as schema does not matter. It does not say that. It says there is no AI specific vocabulary to install.
The second document is the one that answers the question this post is about. Google's structured data general guidelines, carrying Last updated 2026-07-10 UTC, set out content, relevance and completeness rules, and the content rules include a direct instruction: do not mark up content that is not visible to readers of the page. The page gives its own example, which is that if the JSON-LD markup describes a performer, the HTML body must describe that same performer. The relevance section adds that structured data must be a true representation of the page content. These are stated as policy for rich results, and the enforcement Google describes is a manual action against a site, not a silent downgrade.
Put the two together and the position is coherent. There is no markup you add to be eligible for an AI answer. There is markup that describes your page, and it is expected to be a description of the page rather than an addition to it. That is a stricter test than validation, because a graph can validate perfectly while describing a document that does not exist. This site has already shown one version of that gap by reading the same JSON-LD twice and getting a perfect score and a zero, where both readings were defensible. The version measured here is simpler and more concrete: does the string in the markup occur in the page?
The reason it matters for generative engine optimization rather than only for rich results is that the retrieval step and the answering step read different things. A retrieval system can lift a value out of a graph cheaply. A system that then checks its answer against the source document has to find that value in the document. If it is not there, the best case is that the value is dropped, and the worst case is that it is quoted with a citation the citation does not support. Neither outcome is observable from a stored capture, so this post reports the markup rather than the outcome, which is the same discipline behind reporting prose parity instead of predicting a citation from it.
-
No AI specific schema existsStated policy The AI features page, Last updated 2025-12-10 UTC, states there is no special schema.org structured data you need to add to appear in those features. -
Markup must be visible contentStated policy The general guidelines, Last updated 2026-07-10 UTC, say not to mark up content that is not visible to readers of the page. -
Markup must represent the pageStated policy The relevance section of the same page requires structured data to be a true representation of the page content. -
What an AI engine does with a mismatchNot documented Neither page states what happens when a value in the graph is absent from the body, and no crawler vendor documents it either.
How 146 text values were counted against the page text
The method is deliberately dull, because the finding is only worth anything if the rule that produced it is stated precisely enough to argue with. Every application/ld+json block in each stored rendered document was parsed and its graph flattened, giving the same 102 typed nodes an earlier count reached. Every property on every node was then walked, and a value was collected when it was a string, when its key did not begin with an at sign, and when it survived three exclusions.
The exclusions are where the judgement sits. Anything that looked like a URL was dropped, meaning any value starting with http, https, mailto, tel, data or a protocol relative slash pair, because a URL is an identifier and nobody expects it printed in the body. Anything matching an ISO date at the start was dropped for the same reason. Anything shorter than three characters after normalisation was dropped as too short to test. What remains is the set of values a person would recognise as words: names, descriptions, headlines, job titles, feature lists, review bodies. The survivors were then deduplicated after normalisation, so a string that appears in five nodes counts once, which is why 146 distinct values come out of a graph containing several hundred property occurrences.
The comparison itself is the normalisation this scanner already uses for prose parity, applied to both sides. Both the markup value and the page's full visible text are lowercased, stripped of punctuation, and collapsed to single spaces, and the test is whether the normalised value occurs as a substring of the normalised page text. Visible text here means everything the extractor treats as rendered content, including navigation, headers and footers, not just the main content, which is the more generous of the two available corpora. It is worth being explicit that this set is mostly furniture: a previous count found that half the text blocks were navigation, 1,395 of 2,729 across the same five pages. Using the wider corpus makes a value easier to find, so it pushes the result towards present rather than absent.
This test is strict in one direction and generous in the other, and both directions should be held in mind when reading the number. It is strict because a page that paraphrases its own markup, splits a phrase across two elements in a way that changes the word order, or hyphenates differently will register as absent. It is generous because a coincidental match anywhere on the page counts as present, so a common single word name will match text that has nothing to do with the entity. The first effect inflates the 70. The second inflates the 76. Neither is corrected for, and the raw counts are reported rather than an adjusted figure, for the same reason this scanner prefers withholding a grade to guessing one.
Counted as a text value
- A string value on any property of any typed node
- Key does not begin with an at sign
- At least three characters after normalisation
- Deduplicated after normalisation, so repeats count once
- 146 values across 102 nodes
Excluded before comparison
- Anything beginning http, https, mailto, tel or data
- Anything beginning with a protocol relative slash pair
- Anything beginning with an ISO date
- The at sign keys: type, id, context, graph
- Numbers and booleans, which are not text values
70 of 146 values were not in the page text, and one page held 140 of them
Across the five documents, 76 of the 146 distinct values were found in the page's visible text and 70 were not. Stated as a ratio that is 47.9 percent absent, and the ratio is the least useful thing in this post, because the denominator is not spread across five pages in any meaningful way. The Webflow homepage publishes 140 of the 146 values and accounts for 67 of the 70 misses. The Wikipedia article publishes four values and misses two. The Gymshark storefront publishes two values and misses one. The Astro homepage and the MDN HTML reference publish no JSON-LD at all, so they contribute nothing to either side of the count and are shown in the table only so the set is complete.
That concentration is not an accident of this measurement, it is the shape of the set, and the same shape has shown up in every count run over these fixtures. One marketing homepage carrying 96 of the 102 nodes is what a page builder emits when it describes its own interface as well as its content; the earlier count found 39 of them describing a navigation menu. So the honest reading of 70 of 146 is not that half the structured data on the web describes absent content. It is that one large graph on one marketing homepage contains a great deal of material that its own page does not repeat, and two of the five documents in the set have no graph to check.
The Wikipedia misses are the most instructive, because they are the two values on the most carefully maintained page in the set. Its Article node carries a headline whose value is a definition of a web crawler as an internet bot that systematically browses the World Wide Web, and that exact sentence does not appear in the rendered article text, which opens with its own phrasing. Its author is an Organization named Contributors to Wikimedia projects, a string the page never prints, which the post on seven schema nodes naming an author already looked at from a different angle. Both values are accurate. Neither is quotable from the document.
The single Gymshark miss is a measurement artefact and is reported as one. Its Organization node carries a sameAs value written as a bare host and path with no scheme, so the URL exclusion did not catch it, and a social profile URL is obviously not expected in the page body. That is one of the 70 that should not be there, and it is the sort of thing that only surfaces when the exclusion rules are written down. The other 69 are values on properties that genuinely carry words. The truncation flag on the Gymshark capture is also worth naming: that document was truncated at capture, so its graph is small for reasons unrelated to what its publisher shipped.
| Page, as captured on 15 July 2026 | JSON-LD blocks | Typed nodes | Distinct text values | Present in page text | Absent from page text |
|---|---|---|---|---|---|
| astro.build homepage | 0 | 0 | 0 | 0 | 0 |
| gymshark.com storefront | 2 | 2 | 2 | 1 | 1 |
| developer.mozilla.org HTML reference | 0 | 0 | 0 | 0 | 0 |
| webflow.com homepage | 1 | 96 | 140 | 73 | 67 |
| en.wikipedia.org Web crawler article | 1 | 4 | 4 | 2 | 2 |
| All five pages | 4 | 102 | 146 | 76 | 70 |
featureList missed 18 of 19, and description missed 15 of 37
Splitting the 146 values by the property they sit on is where the result stops being a ratio and starts being a pattern. Three properties carry 108 of the 146 values between them, and they behave very differently. name carries 52 values and 38 of them are on the page, the best result of any property with real volume, which makes sense because a name is usually the visible label of something the page also shows. description carries 37 and 22 are present, so roughly two in five descriptions are written for the graph rather than lifted from the body. featureList carries 19 and exactly one of them appears in the page text.
That last figure is the sharpest thing in the measurement. Schema.org defines featureList as features or modules provided by an application, used on SoftwareApplication, with an expected value of text or a URL. The values on this page are ordinary product feature sentences of the kind a marketing site normally prints in a grid, and 18 of the 19 are not printed anywhere on the page carrying them. A reader of that document cannot verify a single one of those 18 claims against the document. A retrieval system that lifts them has taken a vendor's self description with nothing behind it, which is a different kind of evidence from a sentence the page is willing to show.
The rest of the distribution is short tailed and worth reading for what it says about which properties get written honestly. reviewBody missed only 1 of 6, because a testimonial is quoted on the page in order to be persuasive, so its markup and its body agree almost by construction. jobTitle missed 4 of 9 and audienceType missed 4 of 6. Then there is a long tail of thirteen properties carrying one value each, all of which are absent: a founding date, a street address, a locality, a postal code, an available language, a contact type, an application category, a rating value, a rating count, a language, a role name, a headline and a text. Several of those are controlled or enumerated values that nobody would expect printed in the body, and counting them as absent is technically correct and analytically weak.
So it is worth stating the stricter number as well. Restricting the count to the properties that genuinely carry human prose, which are name, description, featureList, jobTitle, roleName, reviewBody, abstract, headline and text, gives 127 values of which 55 are absent, or 43.3 percent. That is a smaller and more defensible figure than 70 of 146, it is the one to quote if only one number is quoted, and it moves the finding from about half to about two in five without changing what the finding is. The same instinct applies here that applied when this site found that review authenticity is not in the markup: the property that validates and the property that answers a reader's question are frequently not the same property.
What this does not show, and what the scanner scores instead
The limits are larger than the finding, so they go before the conclusion rather than after it. Five documents captured on a single day is not a sample of anything, one of them supplies 140 of the 146 values, two supply none, and one was truncated at capture. No claim here generalises to the web, to a sector, or to any AI crawler behaviour. Nothing in this measurement shows that an absent value is penalised, discounted or even noticed by any system, because that is not observable from a stored page, and no crawler vendor documents a rule about it. The one authority quoted is Google's, it is about rich results rather than AI answers, and it is a policy rather than a measured effect.
The substring test is also crude in a way that a reader should be able to price. It cannot tell a paraphrase from a contradiction, so a page that says the same thing in different words is scored identically to a page that says nothing of the kind. It cannot tell a meaningful match from a coincidence, so a one word name that happens to appear in a footer counts as present. A stricter test would compare meaning rather than characters, and that would need a model, which would make the result unreproducible from the repository. The crude test is chosen because anyone can rerun it and get the same number.
On the scanner's own behaviour, the honest answer is that it does not check this at all. SCHEMA_REQUIREMENTS in core/src/schema.ts holds five short lists: name and url for an Organization, name for a Product, headline for an Article, mainEntity for a FAQPage, itemListElement for a BreadcrumbList. The schema sub-score confirms that a block parses, that its entities carry a type, and that recognised types carry those properties. Whether a value corresponds to anything on the page is not asked. A graph of 140 invented strings and a graph of 140 quoted ones score the same, and the scoring methodology puts that sub-score at 10 percent of the composite against 50 percent for prose parity, so the check that would catch this is both absent and, if added, small.
That is not an argument for adding it tomorrow. This site has already published what happens when a schema check is built on a plausible assumption: the FAQ rich result left Search while FAQPage markup kept scoring, and the Entity Confidence signal set lost two of its original five when they were re-measured. A check that penalised markup for not being repeated in the body would fire on the Wikipedia article, whose two absent values are both accurate, and that is a false positive on the best page in the set. The useful takeaway for anyone doing answer engine optimisation is not a scoring rule but a habit: after you publish a graph, read your own page and find each claim in it. If a claim is not there, either put it on the page or take it out of the graph. That is also the cheapest thing you can do before worrying about which of the 16 schema types that reach ten million domains you should adopt, or about how to get cited in Google AI Overviews.
- Block parses as JSON 10 pts A block that does not parse scores nothing for that block.
- Entities carry a type 10 pts An untyped object is not a recognised entity.
- Required properties per type 10 pts Five lists in SCHEMA_REQUIREMENTS: Organization, Product, Article, FAQPage, BreadcrumbList.
- Value appears in the page body Not checked anywhere in the scanner. A graph of invented strings scores what a graph of quoted strings scores.
- Value is true Not checkable from a stored page by any automated method this repository has.
Lantad
Published .
Every guide to being cited by an answer engine tells you to add structured data, and Google's own documentation tells you that no special markup is required for its AI features. Both of those are true at once, and the space between them is where the interesting question lives. If schema is not a switch that turns on a rich result, what is it for? The most defensible answer is that it is a machine readable claim about what the page says, useful to any reader that wants to check a fact quickly rather than infer it from prose. That answer has a condition attached, and the condition is testable: the page has to actually say the thing.
Common questions
Does structured data for AI have to match the visible page?
Google's structured data general guidelines, carrying Last updated 2026-07-10 UTC, say you should not mark up content that is not visible to readers of the page, and give the example that if the JSON-LD describes a performer, the HTML body must describe that same performer. The relevance section requires structured data to be a true representation of the page content. Those are Google's rules for rich results and manual actions. No crawler vendor documents what an AI answer engine does when a markup value is absent from the body, so the honest statement is that the rule exists and its effect on AI answers is not published.
How many markup values on real pages are missing from the page text?
On the five pages Lantad captured and stored on 15 July 2026, parsed on 26 August 2026, 70 of 146 distinct human readable JSON-LD text values do not appear in the visible text of the page publishing them. Restricted to the properties that carry prose rather than controlled values, the figure is 55 of 127, or 43.3 percent. One page contributes 140 of the 146 values and two of the five publish no JSON-LD at all, so this is a description of five documents rather than a survey.
Is there special schema.org markup for AI Overviews or AI Mode?
No. Google's page on AI features and your website, carrying Last updated 2025-12-10 UTC, states that you do not need to create new machine readable files, AI text files or markup to appear in those features, and that there is also no special schema.org structured data you need to add. It states that a page must be indexed and eligible to be shown with a snippet, and that there are no additional technical requirements.
Does Lantad's score check whether markup matches the page?
No. The schema sub-score checks that a JSON-LD block parses, that its entities carry a type, and that recognised types carry their required properties, which are five short lists in core/src/schema.ts. It never compares a value against the page text. That sub-score is 10 percent of the composite against 50 percent for prose parity, so even if the check existed it would be the smallest part of the grade.
See what AI can read on your site
Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.