Article

Connected schema: the JSON-LD an assistant can actually parse

Structured data does two jobs: it names the entity behind a page, and it states what the page is about in a form a machine can read without guessing. When it is missing, an assistant has to infer both — and inference is where citations get lost.

The failure we see most often is not missing markup but disconnected markup: a WebSite block on every page regardless of content, Organization data with no sameAs, and an Article with no author, no datePublished and a headline that does not match the visible heading.

Start with the entity, then the page

  1. One Organization (or Person) block for the site — name, url, logo, and sameAs links to the profiles that prove it is the same entity elsewhere.
  2. One block per page that states what the page is — Article, FAQPage, Product, HowTo, or WebPage. Use the type that matches the page, not the type with the most fields.
  3. Connect the two — the page's block should reference the site entity with publisher or isPartOf, so the model does not read them as unrelated fragments.
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Connected schema: the JSON-LD an assistant can actually parse",
  "datePublished": "2026-09-28",
  "author": { "@type": "Organization", "name": "Aeolith", "url": "https://aeolith.com" },
  "isPartOf": { "@type": "WebSite", "name": "Aeolith", "url": "https://aeolith.com" }
}

The four mistakes that make it unusable

  • The block is injected by JavaScript. A crawler that does not execute scripts never sees it. Structured data must be in the HTML source (check A2, text in raw HTML).
  • headline does not match the <h1>. Two different truths about the same page.
  • Required properties are missing for the type you chose — an Article with no date, a Product with no offers.
  • FAQPage markup disagrees with the visible questions. This one is directly detectable, and it is why our own FAQ list and its markup are generated from a single source.

Verify what you shipped

curl -sS https://example.com/page | \
  python3 -c "import sys,re,json;[json.loads(b) for b in re.findall(r'<script type=\"application/ld\+json\">(.*?)</script>', sys.stdin.read(), re.S)]; print('JSON-LD parses')"

If that raises, the block is not JSON — usually a trailing comma or an unescaped quote from a template. A block that does not parse is worse than no block: it is invisible to the machine and looks like work that was done.

What the report shows

Check B2 (structured data) records the JSON-LD types actually parsed, and check B1 records the visible title and description, so you can see whether the machine-readable statement and the page agree. When they disagree, the report says which one it used.

Check a site