seo-schema-structured-data

Expert guide for Schema.org structured data and JSON-LD implementation. Use when creating schema markup, validating structured data, implementing rich results (FAQ, HowTo, Product, Article, LocalBusiness, Breadcrumb, Organization, etc.), troubleshooting rich snippet eligibility, or understanding Google's structured data requirements.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "seo-schema-structured-data" with this command: npx skills add autom8minds/seo-skills/autom8minds-seo-skills-seo-schema-structured-data

Schema.org Structured Data & JSON-LD


JSON-LD Fundamentals

JSON-LD (JavaScript Object Notation for Linked Data) is Google's recommended format for structured data. It is injected via a <script> tag in the <head> or <body> of an HTML page.

Basic Syntax

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "How to Implement Structured Data",
  "author": {
    "@type": "Person",
    "name": "Jane Smith"
  }
}
</script>

Core Keywords

KeywordPurposeExample
@contextDeclares the vocabulary (always https://schema.org)"@context": "https://schema.org"
@typeSpecifies the entity type"@type": "Article"
@idUnique identifier for an entity (enables cross-referencing)"@id": "https://example.com/#organization"
@graphContains multiple entities in a single JSON-LD block"@graph": [{ ... }, { ... }]

Nesting Entities

Entities can be nested directly or referenced by @id:

{
  "@context": "https://schema.org",
  "@type": "Article",
  "author": {
    "@type": "Person",
    "name": "Jane Smith",
    "@id": "https://example.com/#jane"
  },
  "publisher": {
    "@id": "https://example.com/#organization"
  }
}

Arrays

Use arrays when a property has multiple values:

{
  "@type": "Article",
  "author": [
    { "@type": "Person", "name": "Jane Smith" },
    { "@type": "Person", "name": "John Doe" }
  ]
}

The @graph Pattern (Multi-Entity Pages)

Use @graph to describe multiple entities on a single page (e.g., Organization + WebPage + BreadcrumbList):

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Example Corp",
      "url": "https://example.com"
    },
    {
      "@type": "WebPage",
      "@id": "https://example.com/about/#webpage",
      "url": "https://example.com/about/",
      "name": "About Us",
      "isPartOf": { "@id": "https://example.com/#website" }
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
        { "@type": "ListItem", "position": 2, "name": "About" }
      ]
    }
  ]
}

Google-Supported Schema Types

The following types are recognized by Google and can trigger rich results. Each section lists required (R) and recommended (Rec) properties.


Article (NewsArticle, BlogPosting)

Triggers: article rich result with headline, image, date in search.

PropertyStatusNotes
headlineRMax 110 characters
imageRAt least 696px wide; multiple images recommended
datePublishedRISO 8601 format
dateModifiedRecISO 8601 format
authorRPerson or Organization with name and url
publisherRecOrganization with name and logo
descriptionRecShort summary of the article
mainEntityOfPageRecURL of the page

MCP Tool: Use extract_schema on any article URL to see its current structured data, then generate_schema with type Article to produce compliant markup.


Product (with Offer, AggregateRating)

Triggers: product rich result with price, availability, rating stars.

PropertyStatusNotes
nameRProduct name
imageRAt least one image
descriptionRecProduct description
skuRecStock-keeping unit
brandRecBrand name
offersROffer or AggregateOffer
offers.priceRNumeric price
offers.priceCurrencyRISO 4217 currency code
offers.availabilityRItemAvailability enum (e.g., https://schema.org/InStock)
offers.urlRecURL to buy
aggregateRatingRecAggregateRating with ratingValue and reviewCount
reviewRecIndividual Review objects

Nesting pattern: AggregateRating and Offer nest inside Product:

{
  "@type": "Product",
  "name": "Widget",
  "offers": {
    "@type": "Offer",
    "price": "29.99",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.5",
    "reviewCount": "120"
  }
}

FAQPage (with Question / Answer)

Triggers: expandable FAQ accordion in search results.

PropertyStatusNotes
mainEntityRArray of Question objects
Question.nameRThe question text
Question.acceptedAnswerRAnswer object
Answer.textRThe answer text (HTML allowed)

Rules:

  • Only use FAQPage for pages where the primary content is a list of questions and answers.
  • Each question and answer must be visible on the page.
  • Do not use for forums or single-question pages (use QAPage instead).

HowTo (with HowToStep)

Triggers: step-by-step rich result or carousel.

PropertyStatusNotes
nameRTitle of the how-to
stepRArray of HowToStep objects
step.nameRStep title
step.textRStep instructions
step.imageRecImage for each step
step.urlRecURL anchor to step on page
totalTimeRecISO 8601 duration (e.g., PT30M)
estimatedCostRecMonetaryAmount object
supplyRecHowToSupply items needed
toolRecHowToTool items needed

LocalBusiness (and Subtypes)

Triggers: local knowledge panel, map pack eligibility data.

Subtypes: Restaurant, Dentist, LegalService, RealEstateAgent, MedicalBusiness, etc.

PropertyStatusNotes
nameRBusiness name
addressRPostalAddress object
telephoneRecPhone number
openingHoursSpecificationRecArray of hours
geoRecGeoCoordinates (lat/long)
urlRecWebsite URL
imageRecBusiness photo
priceRangeRece.g., $$ or $10-50
servesCuisineRecFor Restaurant subtype
aggregateRatingRecAggregateRating
reviewRecReview objects

Organization

Triggers: knowledge panel data, logo in search results.

PropertyStatusNotes
nameROrganization name
urlRWebsite URL
logoRImageObject or URL (min 112x112px, square preferred)
sameAsRecArray of social profile URLs
contactPointRecContactPoint object
addressRecPostalAddress
descriptionRecShort description
foundingDateRecISO 8601 date

BreadcrumbList

Triggers: breadcrumb trail in search results replacing the URL.

PropertyStatusNotes
itemListElementRArray of ListItem objects
ListItem.positionRInteger (1-indexed)
ListItem.nameRBreadcrumb label
ListItem.itemR*URL (*omit on last item)

WebSite (with SearchAction for Sitelinks Search Box)

Triggers: sitelinks search box on branded queries.

PropertyStatusNotes
urlRHomepage URL
nameRecSite name
potentialActionRSearchAction object
SearchAction.targetRURL template with {search_term_string}
SearchAction.query-inputR"required name=search_term_string"
{
  "@type": "WebSite",
  "url": "https://example.com/",
  "potentialAction": {
    "@type": "SearchAction",
    "target": "https://example.com/search?q={search_term_string}",
    "query-input": "required name=search_term_string"
  }
}

Event

Triggers: event rich result with date, location, ticket info.

PropertyStatusNotes
nameREvent name
startDateRISO 8601 datetime
locationRPlace or VirtualLocation
location.nameRVenue name
location.addressRPostalAddress
endDateRecISO 8601 datetime
descriptionRecEvent description
imageRecEvent image
offersRecOffer with price/url/availability
performerRecPerson or Organization
organizerRecPerson or Organization
eventStatusRecEventScheduled, EventCancelled, EventPostponed, etc.
eventAttendanceModeRecOfflineEventAttendanceMode, OnlineEventAttendanceMode, MixedEventAttendanceMode

Recipe

Triggers: recipe rich result with image, rating, cook time.

PropertyStatusNotes
nameRRecipe name
imageRMultiple images at different aspect ratios
authorRPerson or Organization
datePublishedRecISO 8601
descriptionRecShort description
prepTimeRecISO 8601 duration
cookTimeRecISO 8601 duration
totalTimeRecISO 8601 duration
recipeYieldRece.g., "4 servings"
recipeIngredientRecArray of strings
recipeInstructionsRArray of HowToStep objects
nutritionRecNutritionInformation (calories)
aggregateRatingRecAggregateRating
videoRecVideoObject

VideoObject

Triggers: video rich result with thumbnail, duration, upload date.

PropertyStatusNotes
nameRVideo title
descriptionRVideo description
thumbnailUrlRThumbnail image URL
uploadDateRISO 8601 date
contentUrlRecDirect URL to video file
embedUrlRecEmbed URL
durationRecISO 8601 duration
interactionStatisticRecView count

Course

Triggers: course rich result in search and Google for Education.

PropertyStatusNotes
nameRCourse title
descriptionRCourse description
providerROrganization offering the course
offersRecOffer with price
courseCodeRecIdentifier
hasCourseInstanceRecCourseInstance with schedule

SoftwareApplication

Triggers: software rich result with rating, price, OS.

PropertyStatusNotes
nameRApp name
operatingSystemRece.g., "Windows 10", "Android"
applicationCategoryRece.g., "GameApplication", "BusinessApplication"
offersROffer with price (use "0" for free)
aggregateRatingRecAggregateRating
reviewRecReview objects

Review

Triggers: review snippet with star rating.

PropertyStatusNotes
itemReviewedRThe entity being reviewed (Product, LocalBusiness, etc.)
authorRPerson who wrote the review
reviewRatingRRating object with ratingValue
reviewRating.bestRatingRecMaximum rating value
reviewRating.worstRatingRecMinimum rating value
datePublishedRecISO 8601 date
reviewBodyRecFull text of the review

Dynamic Schema Generation Patterns

When building pages programmatically, generate schema from your data models:

Server-Side Rendering (Next.js example)

export default function ProductPage({ product }) {
  const schema = {
    "@context": "https://schema.org",
    "@type": "Product",
    "name": product.title,
    "image": product.images,
    "description": product.description,
    "sku": product.sku,
    "brand": { "@type": "Brand", "name": product.brand },
    "offers": {
      "@type": "Offer",
      "price": product.price,
      "priceCurrency": "USD",
      "availability": product.inStock
        ? "https://schema.org/InStock"
        : "https://schema.org/OutOfStock"
    }
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
      />
      {/* Page content */}
    </>
  );
}

CMS Integration Pattern

For WordPress, Shopify, or headless CMS:

  1. Map CMS fields to schema properties in a template or plugin.
  2. Ensure price, availability, and rating data are pulled from the live data source.
  3. Use conditional logic to only output properties that have values.

Validation Approach

Step 1: Rich Results Test (Google)

Step 2: Schema Markup Validator (Schema.org)

Step 3: Google Search Console

  • Check Enhancements section for structured data reports.
  • Monitor errors, warnings, and valid item counts.
  • Review indexing of pages with structured data.

MCP Tool: Use extract_schema on any URL to pull all JSON-LD, Microdata, and RDFa. Use generate_schema with a target type to produce valid markup from page content.


Common Pitfalls

PitfallProblemFix
Invisible contentSchema describes content not visible to usersEnsure every structured data property matches visible page content
Missing required fieldsGoogle ignores incomplete markupAlways include all required properties per type
Wrong @typeUsing a type Google does not support for rich resultsUse only Google-documented types
Fake reviewsSchema includes fabricated ratings or reviewsOnly mark up genuine, real user reviews
Outdated pricesProduct schema shows old priceDynamically generate schema from live data
Multiple conflicting typesTwo Product schemas on one page with different dataUse one canonical schema per entity
Self-referencing issues@id references that point nowhereEnsure every @id reference has a matching definition
Incorrect date formatUsing MM/DD/YYYY instead of ISO 8601Always use YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS+00:00
HTTP image URLsImages referenced over HTTP not HTTPSUse HTTPS URLs for all images
Spam policy violationsMarking up content solely for SEO manipulationFollow Google's structured data spam policies

Related Skills

  • seo-on-page-optimization -- for content and meta tag optimization
  • seo-technical-audit -- for crawlability and indexing issues
  • seo-mcp-tools-expert -- for detailed MCP tool usage

Key MCP Tools for Structured Data

ToolUse For
extract_schemaExtract existing structured data from any URL
generate_schemaGenerate valid JSON-LD markup for a given page and type

See SCHEMA_TEMPLATES.md for ready-to-use JSON-LD templates. See VALIDATION_RULES.md for Google's validation requirements. See RICH_RESULTS_GUIDE.md for which types trigger which rich results.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

seo-on-page-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
General

seo-local-seo

No summary provided by upstream source.

Repository SourceNeeds Review
General

seo-off-page-backlinks

No summary provided by upstream source.

Repository SourceNeeds Review
General

seo-content-strategy

No summary provided by upstream source.

Repository SourceNeeds Review