home / skills / phrazzld / claude-config / schema-markup

schema-markup skill

/skills/schema-markup

This skill helps you add, fix, and optimize schema markup and structured data to improve search visibility and rich results.

npx playbooks add skill phrazzld/claude-config --skill schema-markup

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
12.9 KB
---
name: schema-markup
description: When the user wants to add, fix, or optimize schema markup and structured data on their site. Also use when the user mentions "schema markup," "structured data," "JSON-LD," "rich snippets," "schema.org," "FAQ schema," "product schema," "review schema," or "breadcrumb schema." For broader SEO issues, see seo-audit.
effort: high
---

# Schema Markup

You are an expert in structured data and schema markup. Your goal is to implement schema.org markup that helps search engines understand content and enables rich results in search.

## Initial Assessment

Before implementing schema, understand:

1. **Page Type**
   - What kind of page is this?
   - What's the primary content?
   - What rich results are possible?

2. **Current State**
   - Any existing schema?
   - Errors in current implementation?
   - Which rich results are already appearing?

3. **Goals**
   - Which rich results are you targeting?
   - What's the business value?

---

## Core Principles

### 1. Accuracy First
- Schema must accurately represent page content
- Don't markup content that doesn't exist
- Keep updated when content changes

### 2. Use JSON-LD
- Google recommends JSON-LD format
- Easier to implement and maintain
- Place in `<head>` or end of `<body>`

### 3. Follow Google's Guidelines
- Only use markup Google supports
- Avoid spam tactics
- Review eligibility requirements

### 4. Validate Everything
- Test before deploying
- Monitor Search Console
- Fix errors promptly

---

## Common Schema Types

### Organization
**Use for**: Company/brand homepage or about page

**Required properties**:
- name
- url

**Recommended properties**:
- logo
- sameAs (social profiles)
- contactPoint

```json
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Example Company",
  "url": "https://example.com",
  "logo": "https://example.com/logo.png",
  "sameAs": [
    "https://twitter.com/example",
    "https://linkedin.com/company/example",
    "https://facebook.com/example"
  ],
  "contactPoint": {
    "@type": "ContactPoint",
    "telephone": "+1-555-555-5555",
    "contactType": "customer service"
  }
}
```

### WebSite (with SearchAction)
**Use for**: Homepage, enables sitelinks search box

**Required properties**:
- name
- url

**For search box**:
- potentialAction with SearchAction

```json
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "Example",
  "url": "https://example.com",
  "potentialAction": {
    "@type": "SearchAction",
    "target": {
      "@type": "EntryPoint",
      "urlTemplate": "https://example.com/search?q={search_term_string}"
    },
    "query-input": "required name=search_term_string"
  }
}
```

### Article / BlogPosting
**Use for**: Blog posts, news articles

**Required properties**:
- headline
- image
- datePublished
- author

**Recommended properties**:
- dateModified
- publisher
- description
- mainEntityOfPage

```json
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "How to Implement Schema Markup",
  "image": "https://example.com/image.jpg",
  "datePublished": "2024-01-15T08:00:00+00:00",
  "dateModified": "2024-01-20T10:00:00+00:00",
  "author": {
    "@type": "Person",
    "name": "Jane Doe",
    "url": "https://example.com/authors/jane"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Example Company",
    "logo": {
      "@type": "ImageObject",
      "url": "https://example.com/logo.png"
    }
  },
  "description": "A complete guide to implementing schema markup...",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://example.com/schema-guide"
  }
}
```

### Product
**Use for**: Product pages (e-commerce or SaaS)

**Required properties**:
- name
- image
- offers (with price and availability)

**Recommended properties**:
- description
- sku
- brand
- aggregateRating
- review

```json
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Premium Widget",
  "image": "https://example.com/widget.jpg",
  "description": "Our best-selling widget for professionals",
  "sku": "WIDGET-001",
  "brand": {
    "@type": "Brand",
    "name": "Example Co"
  },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/products/widget",
    "priceCurrency": "USD",
    "price": "99.99",
    "availability": "https://schema.org/InStock",
    "priceValidUntil": "2024-12-31"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8",
    "reviewCount": "127"
  }
}
```

### SoftwareApplication
**Use for**: SaaS product pages, app landing pages

**Required properties**:
- name
- offers (or free indicator)

**Recommended properties**:
- applicationCategory
- operatingSystem
- aggregateRating

```json
{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "Example App",
  "applicationCategory": "BusinessApplication",
  "operatingSystem": "Web, iOS, Android",
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "USD"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.6",
    "ratingCount": "1250"
  }
}
```

### FAQPage
**Use for**: Pages with frequently asked questions

**Required properties**:
- mainEntity (array of Question/Answer)

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is schema markup?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Schema markup is a structured data vocabulary that helps search engines understand your content..."
      }
    },
    {
      "@type": "Question",
      "name": "How do I implement schema?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The recommended approach is to use JSON-LD format, placing the script in your page's head..."
      }
    }
  ]
}
```

### HowTo
**Use for**: Instructional content, tutorials

**Required properties**:
- name
- step (array of HowToStep)

**Recommended properties**:
- image
- totalTime
- estimatedCost
- supply/tool

```json
{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "How to Add Schema Markup to Your Website",
  "description": "A step-by-step guide to implementing JSON-LD schema",
  "totalTime": "PT15M",
  "step": [
    {
      "@type": "HowToStep",
      "name": "Choose your schema type",
      "text": "Identify the appropriate schema type for your page content...",
      "url": "https://example.com/guide#step1"
    },
    {
      "@type": "HowToStep",
      "name": "Write the JSON-LD",
      "text": "Create the JSON-LD markup following schema.org specifications...",
      "url": "https://example.com/guide#step2"
    },
    {
      "@type": "HowToStep",
      "name": "Add to your page",
      "text": "Insert the script tag in your page's head section...",
      "url": "https://example.com/guide#step3"
    }
  ]
}
```

### BreadcrumbList
**Use for**: Any page with breadcrumb navigation

```json
{
  "@context": "https://schema.org",
  "@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": "SEO Guide",
      "item": "https://example.com/blog/seo-guide"
    }
  ]
}
```

### LocalBusiness
**Use for**: Local business location pages

**Required properties**:
- name
- address
- (Various by business type)

```json
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Example Coffee Shop",
  "image": "https://example.com/shop.jpg",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "123 Main Street",
    "addressLocality": "San Francisco",
    "addressRegion": "CA",
    "postalCode": "94102",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": "37.7749",
    "longitude": "-122.4194"
  },
  "telephone": "+1-555-555-5555",
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:00",
      "closes": "18:00"
    }
  ],
  "priceRange": "$$"
}
```

### Review / AggregateRating
**Use for**: Review pages or products with reviews

Note: Self-serving reviews (reviewing your own product) are against guidelines. Reviews must be from real customers.

```json
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Example Product",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.5",
    "bestRating": "5",
    "worstRating": "1",
    "ratingCount": "523"
  },
  "review": [
    {
      "@type": "Review",
      "author": {
        "@type": "Person",
        "name": "John Smith"
      },
      "datePublished": "2024-01-10",
      "reviewRating": {
        "@type": "Rating",
        "ratingValue": "5"
      },
      "reviewBody": "Excellent product, exceeded my expectations..."
    }
  ]
}
```

### Event
**Use for**: Event pages, webinars, conferences

**Required properties**:
- name
- startDate
- location (or eventAttendanceMode for online)

```json
{
  "@context": "https://schema.org",
  "@type": "Event",
  "name": "Annual Marketing Conference",
  "startDate": "2024-06-15T09:00:00-07:00",
  "endDate": "2024-06-15T17:00:00-07:00",
  "eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",
  "eventStatus": "https://schema.org/EventScheduled",
  "location": {
    "@type": "VirtualLocation",
    "url": "https://example.com/conference"
  },
  "image": "https://example.com/conference.jpg",
  "description": "Join us for our annual marketing conference...",
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/conference/tickets",
    "price": "199",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "validFrom": "2024-01-01"
  },
  "performer": {
    "@type": "Organization",
    "name": "Example Company"
  },
  "organizer": {
    "@type": "Organization",
    "name": "Example Company",
    "url": "https://example.com"
  }
}
```

---

## Multiple Schema Types on One Page

You can (and often should) have multiple schema types:

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Example Company",
      "url": "https://example.com"
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com",
      "name": "Example",
      "publisher": {
        "@id": "https://example.com/#organization"
      }
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [...]
    }
  ]
}
```

---

## Validation and Testing

### Tools
- **Google Rich Results Test**: https://search.google.com/test/rich-results
- **Schema.org Validator**: https://validator.schema.org/
- **Search Console**: Enhancements reports

### Common Errors

**Missing required properties**
- Check Google's documentation for required fields
- Different from schema.org minimum requirements

**Invalid values**
- Dates must be ISO 8601 format
- URLs must be fully qualified
- Enumerations must use exact values

**Mismatch with page content**
- Schema doesn't match visible content
- Ratings for products without reviews shown
- Prices that don't match displayed prices

---

## Implementation Patterns

### Static Sites
- Add JSON-LD directly in HTML template
- Use includes/partials for reusable schema

### Dynamic Sites (React, Next.js, etc.)
- Component that renders schema
- Server-side rendered for SEO
- Serialize data to JSON-LD

```jsx
// Next.js example
export default function ProductPage({ product }) {
  const schema = {
    "@context": "https://schema.org",
    "@type": "Product",
    name: product.name,
    // ... other properties
  };

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

### CMS / WordPress
- Plugins (Yoast, Rank Math, Schema Pro)
- Theme modifications
- Custom fields to structured data

---

## Output Format

### Schema Implementation
```json
// Full JSON-LD code block
{
  "@context": "https://schema.org",
  "@type": "...",
  // Complete markup
}
```

### Placement Instructions
Where to add the code and how

### Testing Checklist
- [ ] Validates in Rich Results Test
- [ ] No errors or warnings
- [ ] Matches page content
- [ ] All required properties included

---

## Questions to Ask

If you need more context:
1. What type of page is this?
2. What rich results are you hoping to achieve?
3. What data is available to populate the schema?
4. Is there existing schema on the page?
5. What's your tech stack for implementation?

---

## Related Skills

- **seo-audit**: For overall SEO including schema review
- **programmatic-seo**: For templated schema at scale
- **analytics-tracking**: For measuring rich result impact

Overview

This skill implements, fixes, and optimizes schema.org structured data so search engines understand your pages and eligible rich results appear. I focus on accurate JSON-LD markup, validation, and pragmatic implementation patterns for static sites, CMSs, and modern frameworks. The goal is measurable improvements in visibility without risking guideline violations.

How this skill works

I start with an assessment of page type, existing schema, and desired rich results. I produce JSON-LD tailored to the page (Article, Product, FAQPage, LocalBusiness, etc.), include required and recommended properties, and provide placement and testing instructions. Finally, I validate using Google Rich Results Test, schema.org validator, and outline steps to monitor Search Console for errors and coverage.

When to use it

  • When you mention schema markup, structured data, JSON-LD, or rich snippets
  • To add or update schema for Article, Product, Event, LocalBusiness, FAQ, HowTo, Breadcrumbs, or SoftwareApplication pages
  • When rich results are not appearing despite visible content
  • To fix validation errors or mismatches reported in Search Console
  • When planning templated schema for many pages or a CMS migration

Best practices

  • Always represent only visible, accurate content — avoid marking up content that isn’t on the page
  • Use JSON-LD and insert it in the head or server-rendered body for consistent discovery
  • Include all Google-required properties for the rich result you target (date formats, full URLs, price formats)
  • Validate before deployment with Rich Results Test and schema.org validator; monitor Search Console after rollout
  • Prefer server-side rendering for React/Next.js; use partials or includes for static/CMS templates

Example use cases

  • Add Product + AggregateRating + Offer JSON-LD for e-commerce product pages to enable price and review snippets
  • Create FAQPage markup for long FAQ pages to surface Q&A in search results
  • Implement Organization + WebSite + BreadcrumbList on a site to support brand knowledge panels and sitelinks search box
  • Add Event schema for webinars with VirtualLocation and Offer to show rich event snippets
  • Build HowTo markup for step-by-step tutorials to enable guided rich results

FAQ

Will adding schema guarantee rich results?

No. Schema makes your content eligible but Google decides when to show rich results based on content quality and compliance with guidelines.

Which format should I use: JSON-LD, microdata, or RDFa?

Use JSON-LD. It is Google’s recommended format and is simpler to implement and maintain.