DEV Community

Joseph Anady
Joseph Anady

Posted on • Originally published at thatdevpro.com

Schema.org + JSON-LD: the complete pattern reference

Originally published at thatdevpro.com. Part of ThatDevPro's open SEO + AI framework library. ThatDevPro is an SDVOSB-certified veteran-owned web + AI engineering studio. Open-source AI citation toolkit: github.com/Janady13/aio-surfaces.


JSON-LD Implementation, the @id Graph Pattern, Per-Page Type Selection, and Validation

A comprehensive installation and audit reference for structured data — the machine-readable layer that tells Google, AI crawlers, and other consumers what entities a page is about and how they relate. Every meaningful SERP feature, AI citation, and Knowledge Panel claim depends on this layer being correct. Dual-purpose: installation manual and audit document.

Cross-stack implementation note: the code samples in this framework are written in plain HTML for clarity. For React, Vue, Svelte, Next.js, Nuxt, SvelteKit, Astro, Hugo, 11ty, Remix, WordPress, Shopify, and Webflow equivalents of every pattern below, see framework-cross-stack-implementation.md. For pure client-rendered SPAs (no SSR/SSG) see framework-react.md. For Tailwind-specific concerns (purge, dynamic classes, dark-mode CLS, focus accessibility) see framework-tailwind.md.


1. Document Purpose

This is the canonical reference for schema.org structured data implementation. Schema is no longer optional in 2026 — it is the foundation that lets Google's Knowledge Graph populate, AI search engines extract claims, and SERP rich results render. A site without proper structured data is invisible to half of modern search.

Schema in 2026 differs from schema in 2020 in three critical ways. First, the @id graph pattern (cross-referenced nodes within a single @graph block) has overtaken the older "one schema block per page" approach because it lets entities reference each other across the site. Second, AI search engines (ChatGPT, Perplexity, Claude, Gemini) rely on schema as a primary signal for entity extraction — accurate schema increases citation likelihood. Third, validation is non-negotiable: invalid schema is worse than no schema, because Google penalizes spam markup.

1.1 Required Tools

  • Google Rich Results Testsearch.google.com/test/rich-results — primary validator
  • Schema.org Validatorvalidator.schema.org — comprehensive validator (accepts more types than Google's tool)
  • Google Search Console — Enhancements section — sitewide schema health monitoring
  • Yandex Microdata Validatorwebmaster.yandex.com/tools/microtest/
  • JSON-LD Playgroundjson-ld.org/playground/ — for graph experimentation
  • Schema App / Schema Pro — paid tooling for non-developer environments
  • Yoast SEO / Rank Math — WordPress plugins with schema generators
  • Browser DevTools — Application > Frames > Structured Data
  • curl + jq — extract and inspect JSON-LD from a URL programmatically

1.2 Document Scope

Covers: schema formats, @id graph pattern, the major schema types every site needs, type-specific implementation per content type, validation methodology, sameAs networks, and common pitfalls. Touches but does not exhaust: Knowledge Graph claiming (own framework: framework-knowledgegraph.md), AI citation mechanics (framework-aicitations.md), Local SEO schema (framework-localseo.md).


2. Client Variables Intake

business_type: ""                      # local | ecommerce | publisher | b2b_service | sdvosb
primary_entity: ""                     # Organization name
person_entity: ""                      # Founder/author Person if relevant
website_domain: ""
local_business_subtype: ""             # Restaurant | Plumber | Dentist | etc. — only if local
ecommerce_product_count: 0
existing_schema_present: false
existing_schema_format: ""             # JSON-LD | Microdata | RDFa
existing_schema_validated: false
wikidata_qid_org: ""                   # if claimed
wikidata_qid_person: ""                # if claimed
sameas_targets: []                     # LinkedIn, GitHub, Wikidata, Wikipedia, etc.
known_schema_errors: []
Enter fullscreen mode Exit fullscreen mode

3. Schema Format Decision

Three formats are valid. Pick one and stick with it.

Format Recommendation Why
JSON-LD Use this. Decoupled from rendered HTML; survives template changes; preferred by Google; trivial to maintain.
Microdata Avoid for new builds Inline HTML attributes; brittle; tied to template structure.
RDFa Avoid for new builds Similar drawbacks to Microdata; less common.

JSON-LD lives in a <script type="application/ld+json"> block in the document head (or anywhere in the body — head is conventional). It does not need to mirror the visible HTML.


4. The @id Graph Pattern

This is the single most important pattern in modern schema implementation. Older sites declared one schema block per type per page, with no cross-references. The graph pattern declares all entities in one @graph block with cross-referenced @id URIs, letting Google reconstruct the entity relationships.

4.1 Anatomy of a Graph

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": ["Organization", "ProfessionalService", "LocalBusiness"],
      "@id": "https://example.com/#organization",
      "name": "Example Co",
      "url": "https://example.com/",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q12345",
        "https://www.linkedin.com/company/example",
        "https://github.com/example"
      ],
      "founder": { "@id": "https://example.com/#founder" }
    },
    {
      "@type": "Person",
      "@id": "https://example.com/#founder",
      "name": "Joseph W. Anady",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139592630",
        "https://www.linkedin.com/in/josephanady"
      ],
      "worksFor": { "@id": "https://example.com/#organization" },
      "knowsAbout": ["Technical SEO", "AI search optimization"]
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com/",
      "name": "Example Co",
      "publisher": { "@id": "https://example.com/#organization" }
    },
    {
      "@type": "WebPage",
      "@id": "https://example.com/about/#webpage",
      "url": "https://example.com/about/",
      "name": "About — Example Co",
      "isPartOf": { "@id": "https://example.com/#website" },
      "about": { "@id": "https://example.com/#organization" }
    }
  ]
}
</script>
Enter fullscreen mode Exit fullscreen mode

4.2 The @id Convention

@id values are URIs. Use absolute URLs with a fragment identifier (#) to disambiguate entities on the same page:

  • https://example.com/#organization — the Organization entity
  • https://example.com/#website — the WebSite entity
  • https://example.com/#founder — the Person entity
  • https://example.com/about/#webpage — the About page WebPage entity
  • https://example.com/blog/post-name/#article — an Article entity

The @id does NOT need to resolve to a real URL. It is just a unique identifier within the graph.

4.3 Cross-Page Consistency

Every page on the site declares the same Organization, WebSite, and Person entities (with the same @id URIs). Page-specific entities (WebPage, Article, Service, Product) reference back via @id:

{
  "@type": "Article",
  "@id": "https://example.com/blog/post/#article",
  "headline": "Post Title",
  "author": { "@id": "https://example.com/#founder" },
  "publisher": { "@id": "https://example.com/#organization" },
  "isPartOf": { "@id": "https://example.com/blog/post/#webpage" }
}
Enter fullscreen mode Exit fullscreen mode

This cross-referencing is what gives Google's Knowledge Graph the connectivity it needs to attribute Articles to Authors, Authors to Organizations, and Organizations to Knowledge Panel entries.


5. The Foundation Schemas

Every meaningful site needs these. Implement them sitewide before any page-specific schema.

5.1 Organization

Required for every site. If the business has a physical location, extend with LocalBusiness; if it serves a profession, extend with ProfessionalService.

{
  "@type": ["Organization", "ProfessionalService", "LocalBusiness"],
  "@id": "https://example.com/#organization",
  "name": "Example Co",
  "alternateName": ["example.com", "Example"],
  "url": "https://example.com/",
  "logo": {
    "@type": "ImageObject",
    "url": "https://example.com/logo.png",
    "width": 600,
    "height": 600
  },
  "image": "https://example.com/og-default.png",
  "description": "Plain-English description matching the site's actual purpose.",
  "telephone": "+1-505-512-3662",
  "email": "hello@example.com",
  "priceRange": "$597-$11997",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "123 Main St",
    "addressLocality": "Cassville",
    "addressRegion": "MO",
    "postalCode": "65625",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 36.6811,
    "longitude": -93.8702
  },
  "areaServed": [
    { "@type": "AdministrativeArea", "name": "Northwest Arkansas" },
    { "@type": "AdministrativeArea", "name": "Southwest Missouri" }
  ],
  "founder": { "@id": "https://example.com/#founder" },
  "foundingDate": "2017-01-01",
  "sameAs": [
    "https://www.wikidata.org/wiki/Q139592631",
    "https://www.linkedin.com/company/example",
    "https://github.com/example"
  ]
}
Enter fullscreen mode Exit fullscreen mode

5.2 Person

For owner-operated businesses, sole-proprietor agencies, and any site with named editorial authors. Critical for E-E-A-T.

{
  "@type": "Person",
  "@id": "https://example.com/#founder",
  "name": "Joseph W. Anady",
  "givenName": "Joseph",
  "additionalName": "W.",
  "familyName": "Anady",
  "jobTitle": "Founder",
  "worksFor": { "@id": "https://example.com/#organization" },
  "image": "https://example.com/joseph.jpg",
  "url": "https://example.com/about/",
  "knowsAbout": [
    "Technical SEO", "Local SEO", "AI search optimization",
    "Schema markup", "SDVOSB digital marketing"
  ],
  "knowsLanguage": ["English"],
  "alumniOf": "U.S. Army",
  "sameAs": [
    "https://www.wikidata.org/wiki/Q139592630",
    "https://www.linkedin.com/in/josephanady",
    "https://github.com/josephanady"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Cross-reference: framework-eeat.md for Person schema's role in expertise signals; framework-knowledgegraph.md for sameAs network construction.

5.3 WebSite

Declares the site itself as an entity. Enables sitelinks search box.

{
  "@type": "WebSite",
  "@id": "https://example.com/#website",
  "url": "https://example.com/",
  "name": "Example Co",
  "publisher": { "@id": "https://example.com/#organization" },
  "inLanguage": "en-US",
  "potentialAction": {
    "@type": "SearchAction",
    "target": {
      "@type": "EntryPoint",
      "urlTemplate": "https://example.com/search?q={search_term_string}"
    },
    "query-input": "required name=search_term_string"
  }
}
Enter fullscreen mode Exit fullscreen mode

5.4 WebPage (per-page)

Every page declares itself as a WebPage. Subtypes when applicable: AboutPage, ContactPage, FAQPage, CollectionPage.

{
  "@type": "WebPage",
  "@id": "https://example.com/about/#webpage",
  "url": "https://example.com/about/",
  "name": "About — Example Co",
  "description": "About page meta description.",
  "isPartOf": { "@id": "https://example.com/#website" },
  "about": { "@id": "https://example.com/#organization" },
  "primaryImageOfPage": {
    "@type": "ImageObject",
    "url": "https://example.com/about-hero.jpg"
  },
  "datePublished": "2026-01-15",
  "dateModified": "2026-05-05",
  "breadcrumb": { "@id": "https://example.com/about/#breadcrumb" }
}
Enter fullscreen mode Exit fullscreen mode

5.5 BreadcrumbList

For every non-homepage. Drives breadcrumb display in SERPs.

{
  "@type": "BreadcrumbList",
  "@id": "https://example.com/about/#breadcrumb",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://example.com/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "About",
      "item": "https://example.com/about/"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

6. Per-Content-Type Schemas

6.1 Article (blog post, news story, editorial)

Use Article, NewsArticle, BlogPosting, or TechArticle depending on content. Article is the safe default.

{
  "@type": "Article",
  "@id": "https://example.com/blog/post-slug/#article",
  "headline": "Post headline (under 110 characters)",
  "description": "Meta description.",
  "image": [
    "https://example.com/post-image-1x1.jpg",
    "https://example.com/post-image-4x3.jpg",
    "https://example.com/post-image-16x9.jpg"
  ],
  "author": { "@id": "https://example.com/#founder" },
  "publisher": { "@id": "https://example.com/#organization" },
  "datePublished": "2026-04-15T10:00:00-05:00",
  "dateModified": "2026-05-05T14:30:00-05:00",
  "mainEntityOfPage": { "@id": "https://example.com/blog/post-slug/#webpage" },
  "wordCount": 2500,
  "articleBody": "First 200 characters of body, optional but improves AI extraction.",
  "keywords": ["technical seo", "schema", "json-ld"]
}
Enter fullscreen mode Exit fullscreen mode

Image best practice: provide three images at three aspect ratios (1x1, 4x3, 16x9). Google selects the best fit per surface.

6.2 Service

For service-based businesses describing what they offer.

{
  "@type": "Service",
  "@id": "https://example.com/services/local-seo/#service",
  "name": "Local SEO for Northwest Arkansas",
  "description": "Description of the service offered.",
  "provider": { "@id": "https://example.com/#organization" },
  "serviceType": "Local SEO",
  "areaServed": [
    { "@type": "AdministrativeArea", "name": "Northwest Arkansas" }
  ],
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Local SEO Services",
    "itemListElement": [
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Google Business Profile setup"
        },
        "price": "597",
        "priceCurrency": "USD"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

6.3 Product (ecommerce)

Cross-reference: framework-ecommerceseo.md for full product schema depth.

{
  "@type": "Product",
  "@id": "https://example.com/products/sku-123/#product",
  "name": "Product Name",
  "description": "Product description.",
  "image": ["https://example.com/product.jpg"],
  "sku": "SKU-123",
  "gtin13": "1234567890123",
  "brand": { "@type": "Brand", "name": "Brand Name" },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/products/sku-123/",
    "priceCurrency": "USD",
    "price": "29.99",
    "priceValidUntil": "2026-12-31",
    "availability": "https://schema.org/InStock",
    "itemCondition": "https://schema.org/NewCondition",
    "shippingDetails": { "@type": "OfferShippingDetails" },
    "hasMerchantReturnPolicy": { "@type": "MerchantReturnPolicy" }
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8",
    "reviewCount": "127"
  }
}
Enter fullscreen mode Exit fullscreen mode

aggregateRating is only valid if you actually have those reviews on-site. Fabricating reviews is a manual-action violation. Cross-reference: framework-spampolicies.md.

6.4 LocalBusiness (with subtype)

For local businesses, use the most specific subtype available. Schema.org has hundreds: Restaurant, Plumber, Dentist, HVACBusiness, RealEstateAgent, LegalService, MedicalBusiness, HomeAndConstructionBusiness, etc.

{
  "@type": ["LocalBusiness", "Plumber"],
  "@id": "https://example.com/#organization",
  "name": "Example Plumbing",
  "telephone": "+1-555-555-5555",
  "address": { "@type": "PostalAddress", "..." : "..." },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:00",
      "closes": "17:00"
    }
  ],
  "priceRange": "$$"
}
Enter fullscreen mode Exit fullscreen mode

Cross-reference: framework-localseo.md for full LocalBusiness depth.

6.5 FAQPage

Only when the page actually answers questions. Misuse triggers manual actions.

{
  "@type": "FAQPage",
  "@id": "https://example.com/faq/#faqpage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "How long does local SEO take to show results?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Most clients see Local Pack improvements within 30-60 days..."
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

FAQ rich results were largely deprecated by Google in 2023 for non-government / non-health sites, but the schema still feeds AI extraction. Keep using it where it accurately describes the page; do not expect rich results.

6.6 HowTo

For genuine step-by-step instructions. Like FAQ, rich results were curtailed in 2023 but the schema remains useful for AI extraction.

{
  "@type": "HowTo",
  "name": "How to claim a Google Business Profile",
  "step": [
    {
      "@type": "HowToStep",
      "name": "Sign in to Google Business Profile",
      "text": "Visit business.google.com and sign in..."
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

6.7 Event

For dated events.

{
  "@type": "Event",
  "name": "Workshop on Local SEO",
  "startDate": "2026-06-15T18:00:00-05:00",
  "endDate": "2026-06-15T20:00:00-05:00",
  "location": {
    "@type": "Place",
    "name": "Cassville Chamber",
    "address": { "@type": "PostalAddress", "..." : "..." }
  },
  "organizer": { "@id": "https://example.com/#organization" },
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode"
}
Enter fullscreen mode Exit fullscreen mode

6.8 Review (single review)

When a page is genuinely a single review of one product/service.

{
  "@type": "Review",
  "itemReviewed": { "@type": "Product", "name": "Product Name" },
  "author": { "@id": "https://example.com/#founder" },
  "reviewRating": {
    "@type": "Rating",
    "ratingValue": "4.5",
    "bestRating": "5"
  },
  "datePublished": "2026-04-01"
}
Enter fullscreen mode Exit fullscreen mode

6.9 VideoObject

For pages embedding or hosting video. Required for video sitemap inclusion.

{
  "@type": "VideoObject",
  "name": "Video Title",
  "description": "Video description.",
  "thumbnailUrl": ["https://example.com/thumb.jpg"],
  "uploadDate": "2026-04-01T08:00:00-05:00",
  "duration": "PT5M30S",
  "contentUrl": "https://example.com/video.mp4",
  "embedUrl": "https://www.youtube.com/embed/abc123"
}
Enter fullscreen mode Exit fullscreen mode

Cross-reference: framework-videoseo.md for full video implementation.

6.10 Other Useful Types

  • Course — for educational content
  • Recipe — for food sites
  • JobPosting — for hiring pages
  • RealEstateListing — for property listings
  • MedicalCondition / Drug — for YMYL medical content (high standard required)
  • SoftwareApplication — for tools/apps
  • DataCatalog / Dataset — for structured data publishers
  • ItemList — for lists of any kind

7. The sameAs Network

sameAs declares external canonical identifiers for an entity. This is how Google's Knowledge Graph builds entity confidence.

7.1 sameAs Hierarchy of Trust

Source Weight Notes
Wikidata Highest Entity ID format: https://www.wikidata.org/wiki/Q12345
Wikipedia Very high Article URL
Crunchbase (orgs) High Verified company entries
LinkedIn (orgs and persons) High Verified accounts
GitHub (devs/orgs) High when relevant
Twitter/X Medium Verified accounts only
Facebook Medium Page (not personal)
Instagram Medium Business profiles
YouTube Medium Channel URL
Personal website Low (when used as sameAs from another entity)
Random social network Low Avoid noise

Cross-reference: framework-knowledgegraph.md for Wikidata claiming methodology.

7.2 sameAs Hygiene

  • Only declare sameAs for entities you actually own and control.
  • Verify each sameAs target resolves and represents the same entity.
  • Do not include URL shorteners or redirects in sameAs.
  • Update sameAs when external profiles move.
  • Both directions matter: the external profile should also link back to the canonical site.

8. Schema Implementation Patterns

8.1 The Sitewide Block

Every page on the site emits the same Organization, WebSite, and Person entities. Implement once in your template head:

<!-- Sitewide schema graph (every page) -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    { /* Organization */ },
    { /* Person */ },
    { /* WebSite */ }
  ]
}
</script>
Enter fullscreen mode Exit fullscreen mode

8.2 The Page-Specific Block

Each page adds its specific entities (WebPage, Article, BreadcrumbList, etc.) referencing the sitewide entities via @id. Two valid patterns:

Pattern A: Two separate script tags

  • Sitewide block in template head
  • Page-specific block in template body or a content-type-specific include

Pattern B: Merged graph

  • Single script tag combining sitewide + page-specific entities
  • Cleaner output; more complex template logic

Pattern A is easier to maintain. Pattern B is what Yoast / Rank Math output.

8.3 Dynamic Sites

For React, Next.js, Astro, Hugo, etc., the schema is built from data at render time. Maintain a single schema.ts (or equivalent) module that exports typed builders:

export function organizationSchema(): Organization { /* ... */ }
export function articleSchema(post: Post): Article { /* ... */ }
export function pageSchema(page: Page): WebPage { /* ... */ }
Enter fullscreen mode Exit fullscreen mode

Tests assert the output validates. Cross-reference: framework-nextjs.md, framework-astrohugo.md.

8.4 WordPress Sites

Yoast and Rank Math both output JSON-LD using the @id graph pattern. Verify their output rather than rebuilding. Common gotchas:

  • Yoast and Rank Math both running → duplicate schema. Pick one.
  • Theme adding schema in addition to the plugin → duplicate or conflicting. Strip theme schema.
  • Plugin defaults inadequate (e.g., missing Person schema for the site owner) → use plugin's customization hooks.

9. Validation Methodology

9.1 Per-URL Validation

Three tools to run on every important page:

  1. Google Rich Results Test — confirms Google can parse and what rich results are eligible.
  2. Schema.org Validator — confirms strict schema.org compliance (catches issues Google's tool doesn't).
  3. Yandex Microdata Validator — third opinion; sometimes catches edge cases.

A page that passes all three is in good shape.

9.2 Sitewide Validation

For sites with many URLs, sample-test rather than per-URL:

  • Pick one URL per content type (homepage, About, blog post, service page, product page if ecommerce, etc.)
  • Run the three validators on each
  • Crawl the site with Screaming Frog — Custom Extraction can pull JSON-LD blocks from every URL
  • Programmatically parse and validate (custom script + schema.org's Java validator or a Node lib like structured-data-testing-tool)

9.3 GSC Enhancements Monitoring

Google Search Console's Enhancements section reports schema-related issues sitewide. Categories include Articles, Products, FAQs, How-tos, Breadcrumbs, Sitelinks searchbox, Logos, etc. Check monthly. New errors usually indicate a template change broke schema for a content type.


10. Schema for AI Search

In 2026, AI search engines (ChatGPT, Perplexity, Claude, Gemini, Copilot) use schema as a primary signal for entity extraction. Practical implications:

10.1 Make Claims Extractable

AI engines parse schema looking for atomic facts: "Joseph W. Anady is the founder of That Stupid Computer," "That Stupid Computer is a SDVOSB business in Cassville, Missouri." Express these as schema:

  • founder relationship between Person and Organization
  • address.addressLocality for the city
  • award, honorificPrefix, certifications declared on Person
  • description written as plain prose, not marketing copy

10.2 Don't Hide Facts in Prose Only

A page can have a clear fact in body text ("we serve all of Northwest Arkansas") but if it isn't also in the schema (areaServed), AI engines may miss it.

10.3 Use Specific Subtypes

Organization is too generic. LocalBusiness is better. Plumber (a LocalBusiness subtype) is best because it matches a query category. AI search engines weight specificity.

10.4 The answer-capsule Pattern

Pair schema with a 200-300 word "answer capsule" paragraph in the visible page content that AI extractors can copy verbatim. The schema gives them entity confidence; the prose gives them the quote. Cross-reference: framework-aicitations.md.


11. Audit Mode

# Criterion Pass/Fail
SC1 Format is JSON-LD (not Microdata or RDFa)
SC2 Sitewide Organization schema present on every page
SC3 Sitewide WebSite schema present on every page
SC4 Person schema for owner/key author present and referenced from Organization
SC5 Per-page WebPage schema present, references WebSite via @id
SC6 BreadcrumbList present on every non-homepage
SC7 @id graph pattern used (entities cross-reference via @id, not duplicated)
SC8 All @id values are absolute URLs with fragment identifier
SC9 sameAs network includes Wikidata Q-ID where claimed
SC10 sameAs network includes 3+ authoritative external profiles
SC11 Article schema on every editorial page with author + publisher refs
SC12 Service or Product schema on every commercial page
SC13 LocalBusiness with specific subtype if local business
SC14 All schema URLs use HTTPS
SC15 Image fields point to existing assets, correct dimensions
SC16 datePublished and dateModified accurate (not faked)
SC17 aggregateRating only present if reviews actually exist
SC18 FAQPage schema only on pages that genuinely answer questions
SC19 No deprecated types (hCard, hReview, etc.)
SC20 Google Rich Results Test passes for sample of 5+ pages
SC21 Schema.org Validator passes for sample of 5+ pages
SC22 GSC Enhancements section shows zero errors (warnings acceptable)
SC23 No duplicate schema (multiple plugins emitting overlapping blocks)
SC24 sameAs targets verified to resolve and represent same entity
SC25 Schema present in initial HTML (not added by client-side JS)
SC26 Schema identical on mobile and desktop
SC27 Article images provided in 1x1, 4x3, 16x9 ratios
SC28 Wikidata Q-ID present in Person and Organization sameAs if claimed
SC29 Specific LocalBusiness subtype used (not generic LocalBusiness)
SC30 Sitewide schema validated quarterly

Score: 30. World-class: 28+/30.


12. Common Mistakes

  1. Microdata or RDFa instead of JSON-LD. Maintainability nightmare.
  2. One schema per page, no @graph. Misses the cross-referencing benefit.
  3. No Person schema. Erases E-E-A-T author signals.
  4. Generic LocalBusiness. Plumber or Dentist is far stronger than LocalBusiness.
  5. Fabricated aggregateRating. Manual-action territory.
  6. FAQ schema on pages that aren't FAQs. Same.
  7. Schema added by client-side JavaScript. Some crawlers see it; many don't.
  8. Duplicate schema from multiple plugins. Yoast + Rank Math + theme = three Organization blocks. Conflicting signals.
  9. @id values that aren't URIs. Use absolute URLs with # fragments.
  10. Image fields pointing to broken assets. Schema validates but rich results don't show.
  11. datePublished after dateModified. Logical impossibility, occasionally happens.
  12. sameAs targets that don't resolve. Dead links erode signal.
  13. Schema on staging visible to crawlers. Robots-blocked staging still gets indexed sometimes; schema there pollutes the entity graph.
  14. Schema not updated when content changes. Stale wordCount, stale dateModified, stale description.
  15. Skipping BreadcrumbList. Trivial to implement, immediate SERP benefit.
  16. Over-decorating schema with marketing language. "Best plumber in Cassville" in description instead of plain prose. AI extractors discount marketing phrases.

13. Maintenance

Weekly:

  • Spot-check newly published content for correct schema
  • Monitor GSC Enhancements for new errors

Monthly:

  • Sitewide validation sample (5 representative URLs through Rich Results Test)
  • Review GSC Enhancements report
  • Verify sameAs targets still resolve

Quarterly:

  • Comprehensive schema audit (every content type sampled)
  • Validate Wikidata Q-IDs still claimed
  • Refresh any schema fields that depend on counted data (review counts, post counts, etc.)
  • Review new Schema.org types released; adopt where applicable

Annually:

  • Full sitewide JSON-LD extraction and programmatic validation
  • Review schema strategy against new SERP features and AI search developments
  • Verify schema authoring tools (plugins, modules) are up to date

14. Companion Documents

  • framework-knowledgegraph.md — Wikidata claiming, Knowledge Panel, sameAs network construction
  • framework-eeat.md — Person schema's role in E-E-A-T signals
  • framework-localseo.md — LocalBusiness subtype selection and full local schema depth
  • framework-aicitations.md — Schema's role in AI search citation
  • framework-ecommerceseo.md — Product schema, MerchantReturnPolicy, OfferShippingDetails
  • framework-videoseo.md — VideoObject and video sitemap
  • framework-spampolicies.md — Schema spam policies (fabricated reviews, FAQ misuse)
  • framework-internallinking.md — BreadcrumbList placement strategy
  • framework-technicalseo.md — Schema's place in the indexing pipeline

Document version: 1.0
Last updated: 2026-05-05
Owner: Joseph W. Anady — ThatDeveloperGuy — SDVOSB


About this framework library

This article is the Dev.to republish of a framework reference document from ThatDevPro's SEO + AI engineering library. Canonical source: https://www.thatdevpro.com/insights/framework-schema/

ThatDevPro is an SDVOSB-certified veteran-owned web + AI engineering studio operating from Cassville, Missouri. The studio runs the full 14-tier Engine Optimization stack and ships open-source tooling for AI citation engineering.

Companion 14-tier Engine Optimization stack (each tier is its own article):

  1. Tier 1 — Foundation
  2. Tier 2 — Search Visibility
  3. Tier 3 — AI Domination
  4. Tier 4 — Entity and Authority
  5. Tier 5 — Local Domination
  6. Tier 6 — Content and Multimedia
  7. Tier 7 — Social and Community
  8. Tier 8 — Data, Analytics, Conversion
  9. Tier 9 — Monitoring and Intelligence
  10. Tier 10 — Workflow and Operations
  11. Tier 11 — Marketplace and Retail
  12. Tier 12 — International
  13. Tier 14 — Advanced and Immersive

Need this framework implemented on your site? See the Engine Optimization service or hire through ThatDevPro contact.

Top comments (0)