squirrelscan
GitHub

Expected schema for page type: what each kind of page should declare

A page the classifier confidently reads as a product, article, contact or docs page that declares none of the structured data that type should carry. squirrel names the type and the schema to add.

What this rule asks

The per-type schema rules start from the markup: schema/product only looks at a page that already declares Product, so a product page with no structured data passes it. This rule starts from the page instead. The bundled page classifier reads how a page is built and labels it a product page, an article, a contact page and so on. If it is sure, and the page declares none of the schema.org types that kind of page should carry, that is a finding.

Structured data is what makes a product page eligible for product rich results, an article eligible for article rich results, and a contact or about page legible to a search engine or an agent as the business behind the site. A page the model reads one way and the markup says nothing about is usually a template or CMS gap.

What squirrel checks

The rule runs on every crawled page and emits one check named expected-type. It reads the page type the classifier stored for the page and the types the page declares: JSON-LD nodes at any depth, including @graph members and nested ones such as the mainEntity of a WebPage, microdata itemtype values and RDFa typeof values. Types are compared case-insensitively, and a prefix such as https://schema.org/ or schema: is ignored.

Only a page type the model answered is trusted, and only at or above the min_confidence option (0.9 by default). When the classifier fell back to its rules path, the label came from the page’s own JSON-LD @type or og:type, so judging the markup against it would be circular. The rule is also silent for a page with no classification at all, which is what you get with --no-classifier or classifier.enabled = false.

  • Info with the message Page type not classified with enough confidence to expect structured data, when the page has no classification, the label came from the rules path, or the confidence is below min_confidence.
  • Info with the message No structured data expected for this page type and the label as the value, for the page types that carry no expectation: homepage, legal, pricing, other and unknown. The site-level WebSite and Organization nodes have their own rules, schema/entity-website-missing and schema/entity-organization-missing.
  • Pass with the message <Page noun> declares <type> when the page declares at least one type from the family for its label. The type is the spelling the page used. The nouns are in the table below.
  • Pass with the message Page declares <type>, read as a listing when the page is read as an article, blog_post or product_detail, declares none of that family, and declares CollectionPage, ItemList, SearchResultsPage or Blog. The markup may veto a finding, never create one: a blog index or pillar page the model reads as a post is a listing, and is not asked for Article markup.
  • Info with the message Page markup too large to judge structured data, when the page declares nothing from the family but a read hit one of those bounds. It is not a finding, because a missing schema is not proven.
  • Fail with the message Reads as <a|an> <page noun> but declares no <expected types> structured data, when neither of the above holds. The message does not carry the confidence, so a report groups the failing pages of one page type into one finding. The check carries details with the page type (pageType, with pageTypeSource set to model), the confidence to two decimals, the expected types and the types the page does declare.
Page typeNounSchema types that satisfy it
articlearticleArticle and every type ending in Article, plus Report, BlogPosting, LiveBlogPosting, SocialMediaPosting, DiscussionForumPosting
blog_postblog postthe same family as article
product_detailproduct pageProduct, ProductGroup, ProductModel, IndividualProduct, SomeProducts, Vehicle, Car, SoftwareApplication, MobileApplication, WebApplication
product_listingproduct listingCollectionPage, ItemList, SearchResultsPage, Blog, OfferCatalog
listing_indexlisting pagethe same family as product_listing
docsdocumentation pagethe article family, plus APIReference, HowTo, FAQPage, QAPage
contactcontact pageContactPage, or any organization type
aboutabout pageAboutPage, ProfilePage, Person, or any organization type

An organization type is Organization, Corporation, NGO, Brand, Airline, Consortium, ProfessionalService, EducationalOrganization, GovernmentOrganization, MedicalOrganization, SportsOrganization, PerformingGroup, every LocalBusiness subtype such as Restaurant or Dentist, and any type ending in Business or Organization. JobPosting is not an article.

The listing veto reads only top-level and @graph node types, so a nested isPartOf of type Blog does not turn a post into a listing. The reads are bounded: JSON-LD is read to a depth of 8 and 2,000 objects, microdata and RDFa to 50,000 elements, 5,000 annotated elements and 64 types per attribute. When a bound is hit, or the page has no document, the rule does not claim a schema is missing. Severity is warning and weight is 5. The rule is skipped on a page detected as a soft 404, because an error template says nothing about what the site meant the page to be.

How to fix it

Add JSON-LD that matches what the page is.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "ContactPage",
  "name": "Contact us",
  "url": "https://example.com/contact",
  "mainEntity": {
    "@type": "Organization",
    "name": "Example Ltd",
    "telephone": "+1-555-0100",
    "email": "hello@example.com"
  }
}
</script>
  • Product pages: Product with name, image and offers, for product rich results. schema/product then checks the details.
  • Articles and blog posts: Article or BlogPosting with headline, author and datePublished. schema/article checks those.
  • Listings and collections: CollectionPage or ItemList, ideally with a BreadcrumbList.
  • Documentation: TechArticle, HowTo or FAQPage.
  • Contact and about pages: ContactPage or AboutPage, and an Organization or LocalBusiness with name, url and contact details, so a search engine or an agent can tie the page to the business behind it.

If the classifier misread the page, raise min_confidence or disable the rule. A page that genuinely should carry no markup, such as a one-off landing page filed under the wrong type, is fine to leave.

Rule IDschema/expected-type
CategoryStructured Data
ScopePer-page
Severitywarning
Weight5/10

Options

OptionTypeDefaultDescription
min_confidencenumber0.9Minimum classifier confidence (0 to 1) before a page type is trusted

Configuration example

[rule_options."schema/expected-type"]
min_confidence = 0.95

squirrel config validate reports a value outside 0 to 1. Raising it trades findings for certainty: a page the model labels at 0.92 is flagged at the default and left alone at 0.95.

Enable / disable

Disable this rule

[rules]
disable = ["schema/expected-type"]

Disable all Structured Data rules

[rules]
disable = ["schema/*"]

Enable only this rule

[rules]
enable = ["schema/expected-type"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

  • schema/coverage-outlier: pages missing markup that the rest of their page type carries. That rule compares a page with its siblings; this one compares it with what its type should declare.
  • schema/product: the required properties of a Product that is declared.
  • schema/article: the required properties of an Article that is declared.
  • schema/breadcrumb: the trail on a page that has no BreadcrumbList, read from the classifier’s breadcrumbs section.

Structured data findings ship in every audit next to the core SEO, performance and agent experience rules. See Fix SEO issues with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com and open the Structured Data section of the report. Each finding names the page, the type the classifier read and the schema to add. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close