---
name: "schema_json_ld_builder"
description: "Detect, validate, and generate Schema.org structured data as JSON-LD. Triggers when someone needs JSON-LD markup for a page (Article, Product, FAQPage, HowTo, BreadcrumbList, Organization, Event, Recipe, VideoObject), wants to check structured data against Google's rich-result rules, or asks to validate an existing JSON-LD block."
---

# Schema JSON-LD Builder

## Purpose

Build correct Schema.org JSON-LD for a page, or validate an existing block against the structure rules and Google's current rich-result support. Ships with a working validator (`bin/validate-jsonld.py`) and tested generators in `references/schema-types.md`.

## Workflow

1. **Pick the type.** Match the page's primary content to one type: Article/BlogPosting/NewsArticle for posts, Product for product pages, FAQPage for Q&A content, HowTo for tutorials, Event for events, Recipe for recipes, VideoObject for video pages, LocalBusiness (use the most specific subtype) for local businesses. Supporting types (Organization, WebSite, BreadcrumbList) go alongside, linked by `@id` in one `@graph`. If the content does not match a type, do not force it.
2. **Set expectations first.** Structured data buys rich-result *eligibility*, not rankings, and not guaranteed display. FAQPage and HowTo are valid Schema.org but earn no Google rich result in general Search right now; say that plainly before writing a line. See `references/rich-result-rules.md`.
3. **Draft the block.** Use the worked examples in `references/schema-types.md` as the starting point. Only use facts from the page itself; never invent prices, ratings, dates, or authors.
4. **Run the validator.** Save the block to a file and run `python3 bin/validate-jsonld.py block.json`. Fix every ERROR. Read every WARNING and decide deliberately.
5. **Output.** Hand back the `<script type="application/ld+json">` block ready to drop in `<head>`, plus a one-line note on what rich result the page is eligible for and what test to run next (validator.schema.org, then Google's Rich Results Test).

## Output Contract

Every JSON-LD block delivered must:
- Parse as valid JSON and declare `"@context": "https://schema.org"`.
- Carry the required properties for its type (see references or run the validator).
- Match the visible page content exactly. No hidden-content markup, no fabricated reviews or prices.
- Use ISO 8601 dates, `priceCurrency` on every offer, ascending breadcrumb positions starting at 1.
- Fit in a single script block with `@graph` when multiple nodes are needed, `@id` linking nodes that refer to the same entity.

## Operating Rules

1. **Accuracy rule.** Every factual claim in the markup must come from the page. Unverifiable detail gets cut, never invented.
2. **One primary type per page.** The primary `@type` must be the thing the page is actually about.
3. **Validator before handoff.** No block ships without a PASS (or explicit review of every WARNING) from `bin/validate-jsonld.py`.
4. **Honest framing.** Never promise a rich result. Say what the page is *eligible* for and name the tests (Rich Results Test, validator.schema.org, Search Console) as the remaining steps.
5. **Recheck Google's gallery.** The supported-feature list changes. Before telling someone a type earns a rich result, confirm it at https://developers.google.com/search/docs/appearance/structured-data/search-gallery.
6. **Keep markup maintained.** Tell the requester plainly: when the price, date, rating, or content changes, the block must change with it.

## Worked example

Page: a product listing for a 40L hiking backpack, in stock at $189.

```json
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Alpine Trail Backpack 40L",
  "image": "https://example.com/img/backpack.jpg",
  "description": "A 40-liter hiking pack with an aluminum frame.",
  "brand": { "@type": "Brand", "name": "Alpine" },
  "sku": "ALP-40L-BLK",
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/shop/alp-40l",
    "price": "189.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock"
  }
}
```

This passes `validate-jsonld.py`, makes the page eligible for the Product rich result (price, availability, ratings), and contains nothing the shopper cannot see on the page.
