Structured data can remain valid JSON while naming a property that does not belong to its declared schema.org type. A repeatable URL check catches those vocabulary mismatches and missing markup before a page change reaches search crawlers.
The validator below fits an existing Node.js project and reads JSON-LD, Microdata, and RDFa from the HTML returned by the web server. It downloads the current schema.org vocabulary on each run, so the check is not tied to a bundled vocabulary snapshot.
Server-rendered markup is the boundary for this method because the page fetch does not execute browser JavaScript. Use the Schema Markup Validator for JavaScript-injected entities and the Rich Results Test when the final decision is eligibility for a Google search feature; valid vocabulary alone does not guarantee a rich result.
Steps to validate structured data for a website:
- Install the structured-data validator and HTML extractor under devDependencies in the existing Node.js project's package.json.
$ npm install --save-dev @adobe/structured-data-validator @marbec/web-auto-extractor
- Create check-schema.mjs with the page-fetch and structured-data extraction section.
- check-schema.mjs
import Validator from '@adobe/structured-data-validator'; import WebAutoExtractor from '@marbec/web-auto-extractor'; if (!process.argv[2]) { console.error('Usage: node check-schema.mjs <url>'); process.exit(2); } const targetUrl = new URL(process.argv[2]); const response = await fetch(targetUrl); if (!response.ok) { throw new Error(`Page request failed: ${response.status} ${response.statusText}`); } const html = await response.text(); const extractedData = new WebAutoExtractor({ addLocation: true, embedSource: ['rdfa', 'microdata'], }).parse(html); const itemTypes = ['jsonld', 'microdata', 'rdfa'].flatMap((format) => Object.entries(extractedData[format]).flatMap(([type, items]) => items.map(() => type), ), ); if (itemTypes.length === 0) { console.error('No structured data found.'); process.exit(1); }
- Append the current Schema.org vocabulary and issue-reporting section to check-schema.mjs.
- check-schema.mjs
const vocabularyResponse = await fetch( 'https://schema.org/version/latest/schemaorg-all-https.jsonld', ); if (!vocabularyResponse.ok) { throw new Error(`Schema.org request failed: ${vocabularyResponse.status}`); } const vocabulary = await vocabularyResponse.json(); const issues = await new Validator(vocabulary).validate(extractedData); if (issues.length === 0) { const typeList = [...new Set(itemTypes)].join(', '); console.log(`Valid: ${itemTypes.length} item(s) (${typeList}).`); process.exit(0); } for (const issue of issues) { console.log(`${issue.severity}: ${issue.issueMessage}`); } process.exit(1);
- Run check-schema.mjs against the public canonical page URL, using https://schema.org/ as the verified example.
$ node check-schema.mjs https://schema.org/ Valid: 1 item(s) (WebSite).
A missing entity, unsupported property, request failure, or vocabulary issue returns a nonzero exit status so the same command can gate a build or deployment.