Both formats
JSON-LD (arrays, @graph, nested nodes, @id references and node merging across blocks) and microdata (itemscope, itemtype, itemprop with the right value per element: content, href, src, datetime or text).
GitHub Packages · MIT · Node ≥ 18
Validate JSON-LD and microdata against schema.org and Google rich-result requirements, across your whole built site.
Validate JSON-LD and microdata in a built static site against schema.org types and Google rich-result requirements: parse errors, unknown types, missing required/recommended properties, bad dates, prices, currencies, enums, durations, ratings and breadcrumbs. Text/JSON/SARIF/Markdown, allowlist with expiry, GitHub Action. Zero deps.
1 Point the @mrlouiswright scope at GitHub Packages in .npmrc
@mrlouiswright:registry=https://npm.pkg.github.com2 Install
npm i -D @mrlouiswright/schema-beaconPublished to GitHub Packages, not npmjs.com. GitHub Packages needs a GitHub token with read:packages to install, even for public packages: add //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} to .npmrc or run npm login --registry=https://npm.pkg.github.com.
$ npx schema-beacon distschema-beacon — dist4 page(s), 3 with structured data; types: ListItem×2, Product×2, Article×1, BreadcrumbList×1, Recipe×1, FAQPage×1, Question×1, Answer×1 HIGH blog/post.html:2 Recipe "Cake" is missing "image", required for Recipe rich results [rich-result-required-missing] ↳ fix: Add image.HIGH blog/post.html:2 Answer is missing "text", required for Answer rich results [rich-result-required-missing] ↳ fix: Add text.HIGH blog/post.html:2 Event "Launch" is missing "location", required for Event rich results [rich-result-required-missing] ↳ fix: Add location.HIGH index.html:2 JSON-LD does not parse: Expected double-quoted property name in JSON at position 73 [jsonld-parse-error] ↳ fix: Fix the JSON (trailing commas, unescaped quotes and comments are common causes); validate with JSON.parse.HIGH product.html:2 AggregateRating is missing "ratingCount" or "reviewCount", required for AggregateRating rich results [rich-result-required-missing] ↳ fix: Add ratingCount.... 7 high, 12 medium, 9 low, 2 info✔ Passing (fail-on: none).
Structured data fails quietly. A trailing comma makes the whole JSON-LD block invisible. “"price": "$1,299.00"”, “"availability": "in stock"” and “"datePublished": "14/10/2026"” all look fine to a person, but Google throws them away. A template change drops image from every recipe, and the rich results disappear a few weeks later. schema-beacon reads every page of your build output and checks each JSON-LD block and microdata item. It reports the file, line, severity and a concrete fix, in CI, before you deploy.
CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies. Works on any static build output (Astro, Next.js “output: 'export'”, Eleventy, Hugo, Jekyll, Docusaurus, VitePress, plain HTML) and runs offline: point it at the folder your build writes. By Louis Wright.
JSON-LD (arrays, @graph, nested nodes, @id references and node merging across blocks) and microdata (itemscope, itemtype, itemprop with the right value per element: content, href, src, datetime or text).
Article, BlogPosting and NewsArticle; Product, Offer, AggregateOffer, AggregateRating and Review; BreadcrumbList; FAQPage, QAPage and HowTo; Recipe; Event; JobPosting; LocalBusiness and its subtypes; Organization; VideoObject; SoftwareApplication; Course; Dataset; ProfilePage; DiscussionForumPosting; ImageObject; Movie; Book; ClaimReview. Missing required properties are high and missing recommended ones are low. Top-level requirements aren't applied to nested nodes (an Organization used as publisher, for example).
ISO 8601 dates and durations, absolute and valid URLs, plain-number prices, ISO 4217 currencies, schema.org enumerations (availability, itemCondition, eventStatus, eventAttendanceMode, employmentType) with the correct URL form suggested, rating ranges, breadcrumb positions and URLs, author as a Person/Organization rather than a string, empty values, and unresolved #id references.
unknown types with did-you-mean suggestions (Prodcut → Product), missing @context, and retired or restricted rich results (HowTo, FAQ) reported as info.
text, JSON, SARIF 2.1.0 and Markdown; --fail-on; exit codes 0/1/2; allowlist entries with expiry dates.
# Example
npx schema-beacon dist# Example
npx schema-beacon dist --fail-on medium --no-recommended# Example
npx schema-beacon public --include "products/**" --sarif schema.sarifpermissions:
contents: read
security-events: write # only needed for the SARIF upload
jobs:
schema-beacon:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with: { persist-credentials: false }
- run: npm ci && npm run build # produce the static site first
- uses: MrLouisWright/schema-beacon@v1
with:
path: dist
fail-on: high
sarif: schema-beacon.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always()
with: { sarif_file: schema-beacon.sarif }
| Flag | Description |
|---|---|
| Site | |
--base-url <url> | Public URL of the site, e.g. https://example.com (default: inferred from canonical/og:url) |
--include <globs> | Only check these pages (file or URL path globs, comma-separated) |
--exclude <globs> | Skip these pages |
--clean-urls | Pages are served without .html (about.html -> /about) |
| Checks | |
--no-recommended | Only report required properties, not recommended ones |
| Common | |
-c, --config <file> | JSON config (default: .schema-beacon.json or "schemaBeacon" in package.json) |
-f, --format <fmt> | text (default) | json | sarif | markdown |
--json <file> | Also write a JSON report |
--sarif <file> | Also write SARIF 2.1.0 |
--markdown <file> | Also write Markdown (e.g. for a job summary) |
--fail-on <sev> | critical | high | medium | low | info | none (default: high) |
--list-rules | Print rules and default severities |
--no-fixes | Hide fix suggestions in text output |
--no-color | Disable colours |
Full reference, config file format and API in the README.
Support this project
I build free, open-source tools that help developers ship safer websites. Every coffee helps keep them maintained, documented and free for everyone.
Buy me a coffee (opens Stripe in a new tab)Secure checkout by Stripe