Skip to content

Conversation

@gsriram24
Copy link
Contributor

@gsriram24 gsriram24 commented Jan 7, 2026

Summary

Add validators for commonly-used schema.org types that Google Rich Results supports:

  • LocalBusiness: requires name, address; recommends geo, image, telephone, url, etc.
  • Article (+ BlogPosting, NewsArticle via inheritance): requires headline; recommends author, datePublished, image, etc.
  • Event: requires name, startDate, location (or online eventAttendanceMode)
  • FAQPage: requires mainEntity (with nested Question/Answer validators)
  • QAPage: requires mainEntity, mainEntity.answerCount (Google's Q&A Page requirement)
  • Question: requires name, acceptedAnswer OR suggestedAnswer; recommends text
  • Answer: requires text
  • HowTo: requires name, step; recommends tools, supply, totalTime, etc.
  • WebSite: requires name, url; recommends potentialAction

Automatic Subtype Inheritance

This PR also introduces automatic validator inheritance for schema.org subtypes. When validating a type that doesn't have its own registered validator, the library automatically falls back to parent type validators by traversing the rdfs:subClassOf hierarchy.

Examples:

Subtype Inherits Validation From
Restaurant, Store, Hotel, Dentist LocalBusiness
NewsArticle, BlogPosting, TechArticle Article
MusicEvent, SportsEvent, Festival Event

This enables validation of 100+ schema types without needing individual validator files for each.

How it works:

  1. Direct handler mappings are checked first (priority)
  2. If no direct mapping exists, parent types are looked up from schemaOrgJson
  3. First parent with a registered handler is used

Changes

  • Added 8 new validator files (LocalBusiness.js, Article.js, Event.js, FAQPage.js, HowTo.js, WebSite.js, Question.js, Answer.js)
  • Added #getParentTypes() and #getHandlersForType() methods to validator.js for inheritance
  • Added test fixtures in gallery/ and src/types/__tests__/
  • Minor fix to Product.test.js to filter for errors only

Testing

  • All existing tests pass (228 passing)
  • New tests added for each validator
  • Verified inheritance works for 50+ schema subtypes

Closes #56

…o, and WebSite

Add validators for commonly-used schema.org types that Google Rich Results supports:

- LocalBusiness: requires name, address; recommends geo, image, telephone, etc.
- Article (+ BlogPosting, NewsArticle): requires headline; recommends author, dates, etc.
- Event: requires name, startDate, location/eventAttendanceMode
- FAQPage: requires mainEntity (with Question/Answer validators)
- HowTo: requires name, step; recommends tools, supplies, etc.
- WebSite: requires name, url; recommends potentialAction

Also includes:
- Question and Answer validators for FAQPage support
- Test fixtures in gallery/ and src/types/__tests__/
- Minor fix to Product.test.js to filter for errors only

Closes adobe#56
…o, and WebSite

Add validators for commonly-used schema.org types that Google Rich Results supports:

- LocalBusiness: requires name, address; recommends geo, image, telephone, etc.
- Article (+ BlogPosting, NewsArticle): requires headline; recommends author, dates, etc.
- Event: requires name, startDate, location/eventAttendanceMode
- FAQPage: requires mainEntity (with Question/Answer validators)
- HowTo: requires name, step; recommends tools, supplies, etc.
- WebSite: requires name, url; recommends potentialAction

Also includes:
- Question and Answer validators for FAQPage support
- Test fixtures in gallery/ and src/types/__tests__/
- Minor fix to Product.test.js to filter for errors only

Closes adobe#56
@gsriram24
Copy link
Contributor Author

Hi, would any of the maintainers let me know if this would be considered or if there's anything I missed?

@herzog31 herzog31 added the enhancement New feature or request label Jan 28, 2026
@herzog31 herzog31 requested review from herzog31 and noruiz January 28, 2026 10:11

this.recommended('aggregateRating', 'object'),
this.recommended('geo', 'object'),
this.recommended('image', 'url'),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

: [typeEntry['rdfs:subClassOf']];

return parents.map((p) => {
const id = p['@id'] || p;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it ever possible for p to be null?

].map((c) => c.bind(this));
}

locationOrAttendanceMode(data) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@herzog31 herzog31 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution.

I raised a few inconsistencies compared to the Google Rich Results documentation available at https://developers.google.com/search/docs/appearance/structured-data.


return parents.map((p) => {
const id = p['@id'] || p;
return id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*/
import BaseValidator from './base.js';

export default class WebSiteValidator extends BaseValidator {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This library bases the implementation for attribute constraints on documentation provided by Google at https://developers.google.com/search/docs/appearance/structured-data/search-gallery as the schema.org specification does not mandate required fields.

As the WebSite type is not part of the Google Rich Results gallery, I recommend to not add this handler. A handler like this can be added to the validator as part of your project.

*/
import BaseValidator from './base.js';

export default class HowToValidator extends BaseValidator {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment about the WebSite type applies here as well.

While HowTo is not supported, HowToStep is and already available in the project.


export default class FAQPageValidator extends BaseValidator {
getConditions() {
return [this.required('mainEntity', 'arrayOrObject')].map((c) => c.bind(this));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please additionally check that mainEntity contains at least one item.

https://developers.google.com/search/docs/appearance/structured-data/faqpage#faq-page

this.recommended('eventAttendanceMode'),
this.recommended('eventStatus'),
this.recommended('image', 'arrayOrObject'),
this.recommended('offers', 'arrayOrObject'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please adjust the Offer type to selectively add recommended attributes availability, price, priceCurrency, validFrom and url for when used within an Event type. The Offer type already contains this logic for use with Product as a reference.

this.recommended('endDate', 'date'),
this.recommended('eventAttendanceMode'),
this.recommended('eventStatus'),
this.recommended('image', 'arrayOrObject'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also be an URL as string.

export default class ArticleValidator extends BaseValidator {
getConditions() {
return [
this.required('headline'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the documentation, headline is only a recommended property.

https://developers.google.com/search/docs/appearance/structured-data/article

this.recommended('author', 'arrayOrObject'),
this.recommended('dateModified', 'date'),
this.recommended('datePublished', 'date'),
this.recommended('image', 'arrayOrObject'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be an URL as string as well.

this.recommended('dateModified', 'date'),
this.recommended('datePublished', 'date'),
this.recommended('image', 'arrayOrObject'),
this.recommended('publisher', 'object'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This attribute is optional according to the documentation. Basically recommending that the publisher of an article should not be listed as part of the author attribute, but using publisher.

https://developers.google.com/search/docs/appearance/structured-data/article

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Add validators for LocalBusiness, Article, Event, FAQPage, and other common types, and child schema validation

3 participants