Squire schema-markup
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.
git clone https://github.com/eddiebelaval/squire
T=$(mktemp -d) && git clone --depth=1 https://github.com/eddiebelaval/squire "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/schema-markup" ~/.claude/skills/eddiebelaval-squire-schema-markup && rm -rf "$T"
skills/schema-markup/SKILL.mdCore Workflows
Workflow 1: Primary Action
- Analyze the input and context
- Validate prerequisites are met
- Execute the core operation
- Verify the output meets expectations
- Report results
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
or end of<head><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
{ "@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
{ "@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
{ "@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
{ "@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
{ "@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)
{ "@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
{ "@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
{ "@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)
{ "@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.
{ "@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)
{ "@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:
{ "@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
// 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
// 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:
- What type of page is this?
- What rich results are you hoping to achieve?
- What data is available to populate the schema?
- Is there existing schema on the page?
- 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