Schema markup skill

Generate Schema.org structured data (JSON-LD) for any page type.

by OpenClaudia·MIT license·★ 705 Stars on the repo·GitHub ↗

Use now

Files of Schema markup

OpenClaudia/main1 file shown
SKILL.md
Show the full text609 lines

Schema Markup Generator Skill

You are an expert in Schema.org structured data and Google's rich results requirements. Generate valid, complete JSON-LD markup that maximizes eligibility for Google rich results.

Supported Schema Types

This skill supports the following schema types. When the user asks for schema, determine which type(s) are appropriate based on the page content.

1. Article / BlogPosting / NewsArticle

Use for: Blog posts, news articles, editorial content Rich result: Article carousel, headline in search

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Your Article Title (max 110 characters)",
  "description": "Brief description of the article (max 160 characters)",
  "image": [
    "https://example.com/image-16x9.jpg",
    "https://example.com/image-4x3.jpg",
    "https://example.com/image-1x1.jpg"
  ],
  "datePublished": "2025-01-15T08:00:00+00:00",
  "dateModified": "2025-01-20T10:30:00+00:00",
  "author": [{
    "@type": "Person",
    "name": "Author Name",
    "url": "https://example.com/author/name",
    "jobTitle": "Senior Editor",
    "sameAs": [
      "https://twitter.com/authorhandle",
      "https://linkedin.com/in/authorname"
    ]
  }],
  "publisher": {
    "@type": "Organization",
    "name": "Publisher Name",
    "logo": {
      "@type": "ImageObject",
      "url": "https://example.com/logo.png",
      "width": 600,
      "height": 60
    }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://example.com/article-url"
  },
  "wordCount": 2500,
  "articleSection": "Technology",
  "keywords": ["keyword1", "keyword2", "keyword3"],
  "isAccessibleForFree": true
}

Google requirements:

  • headline is required (max 110 characters)
  • image is required (provide 3 aspect ratios: 16:9, 4:3, 1:1; each > 696px wide)
  • datePublished is required (ISO 8601 format)
  • author.name is required
  • For NewsArticle, also add dateline if applicable
  • For BlogPosting, @type changes to "BlogPosting"

2. Product

Use for: Product pages, e-commerce listings Rich result: Product snippet with price, availability, reviews

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Product Name",
  "description": "Product description",
  "image": [
    "https://example.com/product-1.jpg",
    "https://example.com/product-2.jpg"
  ],
  "sku": "SKU-12345",
  "mpn": "MPN-67890",
  "gtin13": "0123456789012",
  "brand": {
    "@type": "Brand",
    "name": "Brand Name"
  },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/product",
    "priceCurrency": "USD",
    "price": "99.99",
    "priceValidUntil": "2025-12-31",
    "availability": "https://schema.org/InStock",
    "itemCondition": "https://schema.org/NewCondition",
    "seller": {
      "@type": "Organization",
      "name": "Seller Name"
    },
    "shippingDetails": {
      "@type": "OfferShippingDetails",
      "shippingRate": {
        "@type": "MonetaryAmount",
        "value": "0",
        "currency": "USD"
      },
      "deliveryTime": {
        "@type": "ShippingDeliveryTime",
        "handlingTime": {
          "@type": "QuantitativeValue",
          "minValue": 0,
          "maxValue": 1,
          "unitCode": "DAY"
        },
        "transitTime": {
          "@type": "QuantitativeValue",
          "minValue": 1,
          "maxValue": 5,
          "unitCode": "DAY"
        }
      },
      "shippingDestination": {
        "@type": "DefinedRegion",
        "addressCountry": "US"
      }
    },
    "hasMerchantReturnPolicy": {
      "@type": "MerchantReturnPolicy",
      "applicableCountry": "US",
      "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
      "merchantReturnDays": 30,
      "returnMethod": "https://schema.org/ReturnByMail",
      "returnFees": "https://schema.org/FreeReturn"
    }
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.5",
    "bestRating": "5",
    "ratingCount": "142"
  },
  "review": [{
    "@type": "Review",
    "author": {
      "@type": "Person",
      "name": "Reviewer Name"
    },
    "datePublished": "2025-01-10",
    "reviewBody": "Review text here",
    "reviewRating": {
      "@type": "Rating",
      "ratingValue": "5",
      "bestRating": "5"
    }
  }]
}

Google requirements:

  • name is required
  • offers, review, or aggregateRating - at least one required
  • offers.price and offers.priceCurrency required if offers present
  • offers.availability must use Schema.org enum values
  • As of 2024, shippingDetails and hasMerchantReturnPolicy are recommended for merchant listings

3. FAQPage

Use for: FAQ sections, Q&A pages Rich result: Expandable FAQ in search results

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is the first question?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "<p>The answer with <strong>HTML formatting</strong> allowed. You can include <a href=\"https://example.com\">links</a>.</p>"
      }
    },
    {
      "@type": "Question",
      "name": "What is the second question?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Plain text answers also work."
      }
    }
  ]
}

Google requirements:

  • Each Question must have exactly one acceptedAnswer
  • Answer text can include HTML: <h2> through <h6>, <br>, <ol>, <ul>, <li>, <a>, <p>, <b>, <strong>, <i>, <em>
  • Must be visible on the page (not hidden behind tabs/accordions without proper implementation)
  • Google may show up to 3 FAQ rich results per page
  • Do not use for advertising purposes

4. HowTo

Use for: Tutorial pages, step-by-step guides, DIY instructions Rich result: Step-by-step display in search results

{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "How to Do Something",
  "description": "Brief description of the task",
  "image": {
    "@type": "ImageObject",
    "url": "https://example.com/howto-main.jpg",
    "height": "406",
    "width": "305"
  },
  "totalTime": "PT30M",
  "estimatedCost": {
    "@type": "MonetaryAmount",
    "currency": "USD",
    "value": "20"
  },
  "supply": [
    {
      "@type": "HowToSupply",
      "name": "Supply item 1"
    },
    {
      "@type": "HowToSupply",
      "name": "Supply item 2"
    }
  ],
  "tool": [
    {
      "@type": "HowToTool",
      "name": "Tool 1"
    }
  ],
  "step": [
    {
      "@type": "HowToStep",
      "name": "Step 1 Title",
      "text": "Detailed instructions for step 1.",
      "url": "https://example.com/howto#step1",
      "image": "https://example.com/step1.jpg"
    },
    {
      "@type": "HowToStep",
      "name": "Step 2 Title",
      "text": "Detailed instructions for step 2.",
      "url": "https://example.com/howto#step2",
      "image": "https://example.com/step2.jpg"
    }
  ]
}

Google requirements:

  • name is required
  • step array is required with at least one step
  • Each step needs either text or itemListElement with HowToDirection/HowToTip
  • totalTime uses ISO 8601 duration format (PT1H30M = 1 hour 30 minutes)
  • Do not use HowTo for recipes (use Recipe schema instead)

5. Organization

Use for: Homepage, about page, company information Rich result: Knowledge panel, logo in search

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Company Name",
  "alternateName": "Company Abbreviation",
  "url": "https://example.com",
  "logo": {
    "@type": "ImageObject",
    "url": "https://example.com/logo.png",
    "width": 512,
    "height": 512
  },
  "description": "Company description",
  "foundingDate": "2020-01-01",
  "founder": {
    "@type": "Person",
    "name": "Founder Name"
  },
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "123 Main St",
    "addressLocality": "San Francisco",
    "addressRegion": "CA",
    "postalCode": "94102",
    "addressCountry": "US"
  },
  "contactPoint": [{
    "@type": "ContactPoint",
    "telephone": "+1-555-555-5555",
    "contactType": "customer service",
    "areaServed": "US",
    "availableLanguage": "English"
  }],
  "sameAs": [
    "https://twitter.com/company",
    "https://linkedin.com/company/company",
    "https://facebook.com/company",
    "https://github.com/company"
  ],
  "numberOfEmployees": {
    "@type": "QuantitativeValue",
    "minValue": 10,
    "maxValue": 50
  }
}

6. LocalBusiness

Use for: Local business pages, Google Business Profile support Rich result: Local business panel, map results

{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "@id": "https://example.com/#business",
  "name": "Business Name",
  "description": "Business description",
  "url": "https://example.com",
  "telephone": "+1-555-555-5555",
  "email": "[email protected]",
  "image": "https://example.com/storefront.jpg",
  "logo": "https://example.com/logo.png",
  "priceRange": "$$",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "123 Main St",
    "addressLocality": "San Francisco",
    "addressRegion": "CA",
    "postalCode": "94102",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": "37.7749",
    "longitude": "-122.4194"
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "09:00",
      "closes": "17:00"
    },
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday",
      "opens": "10:00",
      "closes": "14:00"
    }
  ],
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.7",
    "bestRating": "5",
    "ratingCount": "312"
  },
  "areaServed": {
    "@type": "City",
    "name": "San Francisco"
  },
  "hasMap": "https://maps.google.com/?cid=123456789"
}

Google requirements:

  • name, address are required
  • Use specific subtypes when possible: Restaurant, Dentist, LegalService, RealEstateAgent, etc.
  • geo coordinates should be accurate to the business location
  • openingHoursSpecification must reflect actual business hours

7. BreadcrumbList

Use for: Any page with breadcrumb navigation Rich result: Breadcrumb trail in search results

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://example.com"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Category",
      "item": "https://example.com/category"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Current Page Title"
    }
  ]
}

Google requirements:

  • position must be sequential starting at 1
  • Last item should not have item (it's the current page)
  • Must match the visible breadcrumb on the page

8. Review / AggregateRating

Use for: Review pages, product reviews, service reviews Rich result: Star rating in search results

{
  "@context": "https://schema.org",
  "@type": "Review",
  "name": "Review Title",
  "reviewBody": "Full review text...",
  "datePublished": "2025-01-15",
  "author": {
    "@type": "Person",
    "name": "Reviewer Name"
  },
  "itemReviewed": {
    "@type": "Product",
    "name": "Product Being Reviewed",
    "image": "https://example.com/product.jpg"
  },
  "reviewRating": {
    "@type": "Rating",
    "ratingValue": "4",
    "bestRating": "5",
    "worstRating": "1"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Review Site Name"
  }
}

Google requirements:

  • author is required (must be a valid Person or Organization)
  • itemReviewed is required
  • reviewRating is recommended
  • Self-serving reviews (reviewing your own product) are against guidelines

Multi-Schema Pages

Most pages need multiple schema types. Combine them using @graph:

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Company Name",
      "url": "https://example.com",
      "logo": "https://example.com/logo.png"
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com",
      "name": "Site Name",
      "publisher": { "@id": "https://example.com/#organization" }
    },
    {
      "@type": "WebPage",
      "@id": "https://example.com/page/#webpage",
      "url": "https://example.com/page/",
      "name": "Page Title",
      "isPartOf": { "@id": "https://example.com/#website" }
    },
    {
      "@type": "Article",
      "mainEntityOfPage": { "@id": "https://example.com/page/#webpage" },
      "headline": "Article Title",
      "author": { "@type": "Person", "name": "Author" },
      "publisher": { "@id": "https://example.com/#organization" },
      "datePublished": "2025-01-15"
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com" },
        { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog" },
        { "@type": "ListItem", "position": 3, "name": "Article Title" }
      ]
    }
  ]
}

Generation Process

When the user asks for schema markup:

  1. Determine page type - Ask what kind of page this is for (or infer from context)
  2. Gather information - Ask for or collect the required fields. If the user provides a URL, fetch it to extract data.
  3. Select schema types - Choose all applicable schemas (most pages need 2-4 types)
  4. Generate JSON-LD - Create complete, valid markup
  5. Validate - Check against Google's requirements for each type
  6. Provide implementation instructions - Tell the user exactly where to place it

Implementation Instructions

For Next.js App Router:

// In your page component or layout
export default function Page() {
  const jsonLd = {/* generated schema */};

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

For Next.js with next/head (Pages Router):

import Head from 'next/head';

export default function Page() {
  const jsonLd = {/* generated schema */};

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

For plain HTML:

<head>
  <script type="application/ld+json">
  {/* generated schema */}
  </script>
</head>

Validation

After generating the markup, remind the user to validate using:

  1. Google Rich Results Test: https://search.google.com/test/rich-results
  2. Schema.org Validator: https://validator.schema.org/

Common Mistakes to Avoid

  • Do not add schema for content that is not visible on the page
  • Do not use Review schema for self-serving reviews of your own business
  • Do not markup content behind a paywall as isAccessibleForFree: true
  • Do not use fake or placeholder data in production schema
  • Do not add AggregateRating without actual user reviews
  • Always use absolute URLs, never relative
  • Always use ISO 8601 date format
  • priceValidUntil must be a future date
  • availability must use full Schema.org URL (e.g., https://schema.org/InStock)
  • Image URLs must be crawlable and indexable
1---
2name: schema-markup
3description: Generate Schema.org structured data (JSON-LD) for any page type. Use when the user says "schema markup", "structured data", "JSON-LD", "rich snippets", "rich results", "FAQ schema", "product schema", "article schema", "breadcrumb schema", "organization schema", "how-to schema", "review schema", or asks about structured data for SEO.
4---
5 
6# Schema Markup Generator Skill
7 
8You are an expert in Schema.org structured data and Google's rich results requirements. Generate valid, complete JSON-LD markup that maximizes eligibility for Google rich results.
9 
10## Supported Schema Types
11 
12This skill supports the following schema types. When the user asks for schema, determine which type(s) are appropriate based on the page content.
13 
14### 1. Article / BlogPosting / NewsArticle
15 
16**Use for:** Blog posts, news articles, editorial content
17**Rich result:** Article carousel, headline in search
18 
19```json
20{
21 "@context": "https://schema.org",
22 "@type": "Article",
23 "headline": "Your Article Title (max 110 characters)",
24 "description": "Brief description of the article (max 160 characters)",
25 "image": [
26 "https://example.com/image-16x9.jpg",
27 "https://example.com/image-4x3.jpg",
28 "https://example.com/image-1x1.jpg"
29 ],
30 "datePublished": "2025-01-15T08:00:00+00:00",
31 "dateModified": "2025-01-20T10:30:00+00:00",
32 "author": [{
33 "@type": "Person",
34 "name": "Author Name",
35 "url": "https://example.com/author/name",
36 "jobTitle": "Senior Editor",
37 "sameAs": [
38 "https://twitter.com/authorhandle",
39 "https://linkedin.com/in/authorname"
40 ]
41 }],
42 "publisher": {
43 "@type": "Organization",
44 "name": "Publisher Name",
45 "logo": {
46 "@type": "ImageObject",
47 "url": "https://example.com/logo.png",
48 "width": 600,
49 "height": 60
50 }
51 },
52 "mainEntityOfPage": {
53 "@type": "WebPage",
54 "@id": "https://example.com/article-url"
55 },
56 "wordCount": 2500,
57 "articleSection": "Technology",
58 "keywords": ["keyword1", "keyword2", "keyword3"],
59 "isAccessibleForFree": true
60}
61```
62 
63**Google requirements:**
64- `headline` is required (max 110 characters)
65- `image` is required (provide 3 aspect ratios: 16:9, 4:3, 1:1; each > 696px wide)
66- `datePublished` is required (ISO 8601 format)
67- `author.name` is required
68- For `NewsArticle`, also add `dateline` if applicable
69- For `BlogPosting`, `@type` changes to `"BlogPosting"`
70 
71---
72 
73### 2. Product
74 
75**Use for:** Product pages, e-commerce listings
76**Rich result:** Product snippet with price, availability, reviews
77 
78```json
79{
80 "@context": "https://schema.org",
81 "@type": "Product",
82 "name": "Product Name",
83 "description": "Product description",
84 "image": [
85 "https://example.com/product-1.jpg",
86 "https://example.com/product-2.jpg"
87 ],
88 "sku": "SKU-12345",
89 "mpn": "MPN-67890",
90 "gtin13": "0123456789012",
91 "brand": {
92 "@type": "Brand",
93 "name": "Brand Name"
94 },
95 "offers": {
96 "@type": "Offer",
97 "url": "https://example.com/product",
98 "priceCurrency": "USD",
99 "price": "99.99",
100 "priceValidUntil": "2025-12-31",
101 "availability": "https://schema.org/InStock",
102 "itemCondition": "https://schema.org/NewCondition",
103 "seller": {
104 "@type": "Organization",
105 "name": "Seller Name"
106 },
107 "shippingDetails": {
108 "@type": "OfferShippingDetails",
109 "shippingRate": {
110 "@type": "MonetaryAmount",
111 "value": "0",
112 "currency": "USD"
113 },
114 "deliveryTime": {
115 "@type": "ShippingDeliveryTime",
116 "handlingTime": {
117 "@type": "QuantitativeValue",
118 "minValue": 0,
119 "maxValue": 1,
120 "unitCode": "DAY"
121 },
122 "transitTime": {
123 "@type": "QuantitativeValue",
124 "minValue": 1,
125 "maxValue": 5,
126 "unitCode": "DAY"
127 }
128 },
129 "shippingDestination": {
130 "@type": "DefinedRegion",
131 "addressCountry": "US"
132 }
133 },
134 "hasMerchantReturnPolicy": {
135 "@type": "MerchantReturnPolicy",
136 "applicableCountry": "US",
137 "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
138 "merchantReturnDays": 30,
139 "returnMethod": "https://schema.org/ReturnByMail",
140 "returnFees": "https://schema.org/FreeReturn"
141 }
142 },
143 "aggregateRating": {
144 "@type": "AggregateRating",
145 "ratingValue": "4.5",
146 "bestRating": "5",
147 "ratingCount": "142"
148 },
149 "review": [{
150 "@type": "Review",
151 "author": {
152 "@type": "Person",
153 "name": "Reviewer Name"
154 },
155 "datePublished": "2025-01-10",
156 "reviewBody": "Review text here",
157 "reviewRating": {
158 "@type": "Rating",
159 "ratingValue": "5",
160 "bestRating": "5"
161 }
162 }]
163}
164```
165 
166**Google requirements:**
167- `name` is required
168- `offers`, `review`, or `aggregateRating` - at least one required
169- `offers.price` and `offers.priceCurrency` required if offers present
170- `offers.availability` must use Schema.org enum values
171- As of 2024, `shippingDetails` and `hasMerchantReturnPolicy` are recommended for merchant listings
172 
173---
174 
175### 3. FAQPage
176 
177**Use for:** FAQ sections, Q&A pages
178**Rich result:** Expandable FAQ in search results
179 
180```json
181{
182 "@context": "https://schema.org",
183 "@type": "FAQPage",
184 "mainEntity": [
185 {
186 "@type": "Question",
187 "name": "What is the first question?",
188 "acceptedAnswer": {
189 "@type": "Answer",
190 "text": "<p>The answer with <strong>HTML formatting</strong> allowed. You can include <a href=\"https://example.com\">links</a>.</p>"
191 }
192 },
193 {
194 "@type": "Question",
195 "name": "What is the second question?",
196 "acceptedAnswer": {
197 "@type": "Answer",
198 "text": "Plain text answers also work."
199 }
200 }
201 ]
202}
203```
204 
205**Google requirements:**
206- Each `Question` must have exactly one `acceptedAnswer`
207- Answer `text` can include HTML: `<h2>` through `<h6>`, `<br>`, `<ol>`, `<ul>`, `<li>`, `<a>`, `<p>`, `<b>`, `<strong>`, `<i>`, `<em>`
208- Must be visible on the page (not hidden behind tabs/accordions without proper implementation)
209- Google may show up to 3 FAQ rich results per page
210- Do not use for advertising purposes
211 
212---
213 
214### 4. HowTo
215 
216**Use for:** Tutorial pages, step-by-step guides, DIY instructions
217**Rich result:** Step-by-step display in search results
218 
219```json
220{
221 "@context": "https://schema.org",
222 "@type": "HowTo",
223 "name": "How to Do Something",
224 "description": "Brief description of the task",
225 "image": {
226 "@type": "ImageObject",
227 "url": "https://example.com/howto-main.jpg",
228 "height": "406",
229 "width": "305"
230 },
231 "totalTime": "PT30M",
232 "estimatedCost": {
233 "@type": "MonetaryAmount",
234 "currency": "USD",
235 "value": "20"
236 },
237 "supply": [
238 {
239 "@type": "HowToSupply",
240 "name": "Supply item 1"
241 },
242 {
243 "@type": "HowToSupply",
244 "name": "Supply item 2"
245 }
246 ],
247 "tool": [
248 {
249 "@type": "HowToTool",
250 "name": "Tool 1"
251 }
252 ],
253 "step": [
254 {
255 "@type": "HowToStep",
256 "name": "Step 1 Title",
257 "text": "Detailed instructions for step 1.",
258 "url": "https://example.com/howto#step1",
259 "image": "https://example.com/step1.jpg"
260 },
261 {
262 "@type": "HowToStep",
263 "name": "Step 2 Title",
264 "text": "Detailed instructions for step 2.",
265 "url": "https://example.com/howto#step2",
266 "image": "https://example.com/step2.jpg"
267 }
268 ]
269}
270```
271 
272**Google requirements:**
273- `name` is required
274- `step` array is required with at least one step
275- Each step needs either `text` or `itemListElement` with `HowToDirection`/`HowToTip`
276- `totalTime` uses ISO 8601 duration format (PT1H30M = 1 hour 30 minutes)
277- Do not use HowTo for recipes (use Recipe schema instead)
278 
279---
280 
281### 5. Organization
282 
283**Use for:** Homepage, about page, company information
284**Rich result:** Knowledge panel, logo in search
285 
286```json
287{
288 "@context": "https://schema.org",
289 "@type": "Organization",
290 "name": "Company Name",
291 "alternateName": "Company Abbreviation",
292 "url": "https://example.com",
293 "logo": {
294 "@type": "ImageObject",
295 "url": "https://example.com/logo.png",
296 "width": 512,
297 "height": 512
298 },
299 "description": "Company description",
300 "foundingDate": "2020-01-01",
301 "founder": {
302 "@type": "Person",
303 "name": "Founder Name"
304 },
305 "address": {
306 "@type": "PostalAddress",
307 "streetAddress": "123 Main St",
308 "addressLocality": "San Francisco",
309 "addressRegion": "CA",
310 "postalCode": "94102",
311 "addressCountry": "US"
312 },
313 "contactPoint": [{
314 "@type": "ContactPoint",
315 "telephone": "+1-555-555-5555",
316 "contactType": "customer service",
317 "areaServed": "US",
318 "availableLanguage": "English"
319 }],
320 "sameAs": [
321 "https://twitter.com/company",
322 "https://linkedin.com/company/company",
323 "https://facebook.com/company",
324 "https://github.com/company"
325 ],
326 "numberOfEmployees": {
327 "@type": "QuantitativeValue",
328 "minValue": 10,
329 "maxValue": 50
330 }
331}
332```
333 
334---
335 
336### 6. LocalBusiness
337 
338**Use for:** Local business pages, Google Business Profile support
339**Rich result:** Local business panel, map results
340 
341```json
342{
343 "@context": "https://schema.org",
344 "@type": "LocalBusiness",
345 "@id": "https://example.com/#business",
346 "name": "Business Name",
347 "description": "Business description",
348 "url": "https://example.com",
349 "telephone": "+1-555-555-5555",
350 "email": "[email protected]",
351 "image": "https://example.com/storefront.jpg",
352 "logo": "https://example.com/logo.png",
353 "priceRange": "$$",
354 "address": {
355 "@type": "PostalAddress",
356 "streetAddress": "123 Main St",
357 "addressLocality": "San Francisco",
358 "addressRegion": "CA",
359 "postalCode": "94102",
360 "addressCountry": "US"
361 },
362 "geo": {
363 "@type": "GeoCoordinates",
364 "latitude": "37.7749",
365 "longitude": "-122.4194"
366 },
367 "openingHoursSpecification": [
368 {
369 "@type": "OpeningHoursSpecification",
370 "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
371 "opens": "09:00",
372 "closes": "17:00"
373 },
374 {
375 "@type": "OpeningHoursSpecification",
376 "dayOfWeek": "Saturday",
377 "opens": "10:00",
378 "closes": "14:00"
379 }
380 ],
381 "aggregateRating": {
382 "@type": "AggregateRating",
383 "ratingValue": "4.7",
384 "bestRating": "5",
385 "ratingCount": "312"
386 },
387 "areaServed": {
388 "@type": "City",
389 "name": "San Francisco"
390 },
391 "hasMap": "https://maps.google.com/?cid=123456789"
392}
393```
394 
395**Google requirements:**
396- `name`, `address` are required
397- Use specific subtypes when possible: `Restaurant`, `Dentist`, `LegalService`, `RealEstateAgent`, etc.
398- `geo` coordinates should be accurate to the business location
399- `openingHoursSpecification` must reflect actual business hours
400 
401---
402 
403### 7. BreadcrumbList
404 
405**Use for:** Any page with breadcrumb navigation
406**Rich result:** Breadcrumb trail in search results
407 
408```json
409{
410 "@context": "https://schema.org",
411 "@type": "BreadcrumbList",
412 "itemListElement": [
413 {
414 "@type": "ListItem",
415 "position": 1,
416 "name": "Home",
417 "item": "https://example.com"
418 },
419 {
420 "@type": "ListItem",
421 "position": 2,
422 "name": "Category",
423 "item": "https://example.com/category"
424 },
425 {
426 "@type": "ListItem",
427 "position": 3,
428 "name": "Current Page Title"
429 }
430 ]
431}
432```
433 
434**Google requirements:**
435- `position` must be sequential starting at 1
436- Last item should not have `item` (it's the current page)
437- Must match the visible breadcrumb on the page
438 
439---
440 
441### 8. Review / AggregateRating
442 
443**Use for:** Review pages, product reviews, service reviews
444**Rich result:** Star rating in search results
445 
446```json
447{
448 "@context": "https://schema.org",
449 "@type": "Review",
450 "name": "Review Title",
451 "reviewBody": "Full review text...",
452 "datePublished": "2025-01-15",
453 "author": {
454 "@type": "Person",
455 "name": "Reviewer Name"
456 },
457 "itemReviewed": {
458 "@type": "Product",
459 "name": "Product Being Reviewed",
460 "image": "https://example.com/product.jpg"
461 },
462 "reviewRating": {
463 "@type": "Rating",
464 "ratingValue": "4",
465 "bestRating": "5",
466 "worstRating": "1"
467 },
468 "publisher": {
469 "@type": "Organization",
470 "name": "Review Site Name"
471 }
472}
473```
474 
475**Google requirements:**
476- `author` is required (must be a valid `Person` or `Organization`)
477- `itemReviewed` is required
478- `reviewRating` is recommended
479- Self-serving reviews (reviewing your own product) are against guidelines
480 
481## Multi-Schema Pages
482 
483Most pages need multiple schema types. Combine them using `@graph`:
484 
485```json
486{
487 "@context": "https://schema.org",
488 "@graph": [
489 {
490 "@type": "Organization",
491 "@id": "https://example.com/#organization",
492 "name": "Company Name",
493 "url": "https://example.com",
494 "logo": "https://example.com/logo.png"
495 },
496 {
497 "@type": "WebSite",
498 "@id": "https://example.com/#website",
499 "url": "https://example.com",
500 "name": "Site Name",
501 "publisher": { "@id": "https://example.com/#organization" }
502 },
503 {
504 "@type": "WebPage",
505 "@id": "https://example.com/page/#webpage",
506 "url": "https://example.com/page/",
507 "name": "Page Title",
508 "isPartOf": { "@id": "https://example.com/#website" }
509 },
510 {
511 "@type": "Article",
512 "mainEntityOfPage": { "@id": "https://example.com/page/#webpage" },
513 "headline": "Article Title",
514 "author": { "@type": "Person", "name": "Author" },
515 "publisher": { "@id": "https://example.com/#organization" },
516 "datePublished": "2025-01-15"
517 },
518 {
519 "@type": "BreadcrumbList",
520 "itemListElement": [
521 { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com" },
522 { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog" },
523 { "@type": "ListItem", "position": 3, "name": "Article Title" }
524 ]
525 }
526 ]
527}
528```
529 
530## Generation Process
531 
532When the user asks for schema markup:
533 
5341. **Determine page type** - Ask what kind of page this is for (or infer from context)
5352. **Gather information** - Ask for or collect the required fields. If the user provides a URL, fetch it to extract data.
5363. **Select schema types** - Choose all applicable schemas (most pages need 2-4 types)
5374. **Generate JSON-LD** - Create complete, valid markup
5385. **Validate** - Check against Google's requirements for each type
5396. **Provide implementation instructions** - Tell the user exactly where to place it
540 
541## Implementation Instructions
542 
543For **Next.js App Router**:
544```tsx
545// In your page component or layout
546export default function Page() {
547 const jsonLd = {/* generated schema */};
548 
549 return (
550 <>
551 <script
552 type="application/ld+json"
553 dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
554 />
555 {/* page content */}
556 </>
557 );
558}
559```
560 
561For **Next.js with next/head (Pages Router)**:
562```tsx
563import Head from 'next/head';
564 
565export default function Page() {
566 const jsonLd = {/* generated schema */};
567 
568 return (
569 <>
570 <Head>
571 <script
572 type="application/ld+json"
573 dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
574 />
575 </Head>
576 {/* page content */}
577 </>
578 );
579}
580```
581 
582For **plain HTML**:
583```html
584<head>
585 <script type="application/ld+json">
586 {/* generated schema */}
587 </script>
588</head>
589```
590 
591## Validation
592 
593After generating the markup, remind the user to validate using:
5941. **Google Rich Results Test:** https://search.google.com/test/rich-results
5952. **Schema.org Validator:** https://validator.schema.org/
596 
597## Common Mistakes to Avoid
598 
599- Do not add schema for content that is not visible on the page
600- Do not use `Review` schema for self-serving reviews of your own business
601- Do not markup content behind a paywall as `isAccessibleForFree: true`
602- Do not use fake or placeholder data in production schema
603- Do not add `AggregateRating` without actual user reviews
604- Always use absolute URLs, never relative
605- Always use ISO 8601 date format
606- `priceValidUntil` must be a future date
607- `availability` must use full Schema.org URL (e.g., `https://schema.org/InStock`)
608- Image URLs must be crawlable and indexable
609 

Discussion

Alternatives

Agentic Browsing ReadinessAudit and fix agent readiness: the Lighthouse Agentic Browsing fraction, accessibility tree for agents, robots.txt and Content-Signal for AI agents, WAF treatment of agent traffic, llms.txt, Markdown delivery, ai-catalog.json, /.well-known discovery files, and WebMCP tools. Exclude AI citability and brand signals (seo-geo) and commerce protocol depth (seo-ecommerce).Marketing · MITBacklink Profile AnalysisBacklink profile analysis: referring domains, anchor text distribution, toxic link detection, competitor gap analysis. Works with free APIs (Moz, Bing Webmaster, Common Crawl) and DataForSEO extension. Use when user says backlinks, link profile, referring domains, anchor text, toxic links, link gap, link building, disavow, or backlink audit.Marketing · MIT/setup-cmsConnect a CMS to notfair SEO tools. Guides users through configuring WordPress, Strapi, Contentful, or Ghost — tests the connection, and writes credentials to .env.local. Once set up, seo-analysis automatically cross- references CMS content against Google Search Console data. Use whenever the user says "connect my CMS", "set up WordPress", "configure Strapi", "add Contentful", "connect Ghost", or "CMS setup". Also trigger if the user asks why no CMS data appears in a seo-analysis report. · MITBacklink checkBacklink profile for any domain — referring domains, authority, anchors, new/lost links, and a side-by-side vs a competitor. Use when asked "check my backlinks", "backlink profile of X", "who links to them", or "link gap vs competitor".Marketing · MIT