Structured data helps search engines understand your content. When implemented correctly, your pages can display rich results—stars, prices, FAQs, and more—directly in search results. This guide covers everything from basics to advanced implementations.
What is Structured Data?
Structured data is a standardized format for providing information about a page. It uses vocabulary from Schema.org and is typically implemented as JSON-LD.
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "How to Implement Structured Data",
"author": {
"@type": "Person",
"name": "John Doe"
}
}
When Google reads this, it understands:
- This page is an Article
- The title is "How to Implement Structured Data"
- The author is John Doe
This enables rich results in search:
┌────────────────────────────────────────────────────┐
│ How to Implement Structured Data │
│ example.com › blog › structured-data │
│ By John Doe · 5 min read · Dec 19, 2025 │
│ Learn how to add structured data to your website...│
└────────────────────────────────────────────────────┘
Why It Matters
Pages with structured data can see:
- 30-40% higher click-through rates with rich results
- Better understanding by search engines
- Voice search optimization (Google Assistant, Siri)
- Knowledge Graph inclusion
JSON-LD vs Microdata vs RDFa
Three formats exist. JSON-LD is Google's recommended format:
| Format | Implementation | Google Preference |
|---|---|---|
| JSON-LD | <script> in head |
Recommended |
| Microdata | Inline HTML attributes | Supported |
| RDFa | Inline HTML attributes | Supported |
JSON-LD advantages:
- Doesn't clutter HTML
- Easy to generate dynamically
- Simple to maintain
- Can be placed anywhere in the document
Essential Schema Types
1. Organization
Tell Google about your company:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Your Company Name",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"sameAs": [
"https://twitter.com/yourcompany",
"https://linkedin.com/company/yourcompany",
"https://github.com/yourcompany"
],
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+1-555-555-5555",
"contactType": "customer service",
"availableLanguage": ["English"]
}
}
</script>
2. WebSite with Search
Enable sitelinks search box:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Your Site Name",
"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"
}
}
</script>
3. Article
For blog posts and news articles:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Your Article Title",
"description": "A brief description of the article",
"image": [
"https://example.com/image-1x1.jpg",
"https://example.com/image-4x3.jpg",
"https://example.com/image-16x9.jpg"
],
"datePublished": "2025-12-19T08:00:00+00:00",
"dateModified": "2025-12-19T10:30:00+00:00",
"author": {
"@type": "Person",
"name": "Author Name",
"url": "https://example.com/author/name"
},
"publisher": {
"@type": "Organization",
"name": "Publisher Name",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.com/article-url"
}
}
</script>
4. Product
For e-commerce product pages:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Product Name",
"image": [
"https://example.com/product-1.jpg",
"https://example.com/product-2.jpg"
],
"description": "Product description goes here",
"sku": "SKU123",
"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"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"reviewCount": "127"
},
"review": {
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5"
},
"author": {
"@type": "Person",
"name": "Happy Customer"
},
"reviewBody": "Great product, highly recommend!"
}
}
</script>
5. FAQ Page
Get expandable FAQs in search results:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is structured data?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Structured data is a standardized format for providing information about a page to search engines."
}
},
{
"@type": "Question",
"name": "How do I implement structured data?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Add JSON-LD scripts to your page's HTML. The recommended placement is in the <head> section."
}
},
{
"@type": "Question",
"name": "Does structured data improve SEO?",
"acceptedAnswer": {
"@type": "Answer",
"text": "While not a direct ranking factor, structured data enables rich results which can significantly improve click-through rates."
}
}
]
}
</script>
6. How-To
Step-by-step instructions:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "How to Build a Website",
"description": "Learn the basics of building a website",
"totalTime": "PT2H",
"estimatedCost": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": "0"
},
"supply": [
{
"@type": "HowToSupply",
"name": "Computer"
},
{
"@type": "HowToSupply",
"name": "Text editor"
}
],
"tool": [
{
"@type": "HowToTool",
"name": "Web browser"
}
],
"step": [
{
"@type": "HowToStep",
"name": "Choose a domain",
"text": "Select and register a domain name for your website.",
"url": "https://example.com/how-to#step1",
"image": "https://example.com/step1.jpg"
},
{
"@type": "HowToStep",
"name": "Set up hosting",
"text": "Choose a web hosting provider and set up your account.",
"url": "https://example.com/how-to#step2",
"image": "https://example.com/step2.jpg"
},
{
"@type": "HowToStep",
"name": "Build your site",
"text": "Create your website using HTML, CSS, and JavaScript.",
"url": "https://example.com/how-to#step3",
"image": "https://example.com/step3.jpg"
}
]
}
</script>
7. Breadcrumb
Navigation breadcrumbs:
<script type="application/ld+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": "Structured Data Guide",
"item": "https://example.com/blog/structured-data"
}
]
}
</script>
8. Local Business
For physical businesses:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Your Business Name",
"image": "https://example.com/storefront.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
},
"url": "https://example.com",
"telephone": "+1-555-555-5555",
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "09:00",
"closes": "17:00"
}
],
"priceRange": "$$"
}
</script>
9. Software Application
For apps and tools:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Your App Name",
"operatingSystem": "Web, iOS, Android",
"applicationCategory": "DeveloperApplication",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"ratingCount": "1024"
}
}
</script>
Next.js Implementation
Dynamic structured data in Next.js App Router:
// app/blog/[slug]/page.tsx
import { Metadata } from 'next';
interface BlogPost {
title: string;
description: string;
image: string;
date: string;
author: string;
slug: string;
}
async function getPost(slug: string): Promise<BlogPost> {
// Fetch post data
}
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.description,
openGraph: {
title: post.title,
description: post.description,
images: [post.image],
type: 'article',
publishedTime: post.date,
authors: [post.author],
},
};
}
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: post.title,
description: post.description,
image: post.image,
datePublished: post.date,
author: {
'@type': 'Person',
name: post.author,
},
publisher: {
'@type': 'Organization',
name: 'Your Site',
logo: {
'@type': 'ImageObject',
url: 'https://example.com/logo.png',
},
},
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<article>
<h1>{post.title}</h1>
{/* Article content */}
</article>
</>
);
}
Validation Tools
Always validate your structured data:
-
Google Rich Results Test
- search.google.com/test/rich-results
- Shows if your page is eligible for rich results
-
Schema Markup Validator
- validator.schema.org
- Validates against Schema.org spec
-
Google Search Console
- Check the "Enhancements" section
- See which rich results are indexed
Programmatic Validation
Validate structured data across your site using an API:
async function validateStructuredData(url) {
const response = await fetch(
`https://api.katsau.com/v1/analyze?url=${encodeURIComponent(url)}`,
{
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}
);
const { data } = await response.json();
// Check structured data
if (data.structuredData && data.structuredData.length > 0) {
console.log('Found structured data:');
data.structuredData.forEach(schema => {
console.log(`- ${schema['@type']}`);
});
} else {
console.log('No structured data found');
}
return data.structuredData;
}
// Audit entire sitemap
async function auditSitemap(urls) {
const results = [];
for (const url of urls) {
const schemas = await validateStructuredData(url);
results.push({
url,
hasStructuredData: schemas.length > 0,
types: schemas.map(s => s['@type']),
});
}
// Report
const withSchema = results.filter(r => r.hasStructuredData);
console.log(`${withSchema.length}/${results.length} pages have structured data`);
return results;
}
Common Mistakes
1. Missing Required Properties
Each schema type has required fields:
// Wrong: Article missing headline
{
"@type": "Article",
"description": "..."
}
// Correct
{
"@type": "Article",
"headline": "Article Title",
"description": "..."
}
2. Invalid Image URLs
Images must be absolute URLs:
// Wrong
"image": "/images/photo.jpg"
// Correct
"image": "https://example.com/images/photo.jpg"
3. Incorrect Date Format
Use ISO 8601 format:
// Wrong
"datePublished": "December 19, 2025"
// Correct
"datePublished": "2025-12-19T08:00:00+00:00"
4. Spammy Content
Don't add structured data for content that doesn't exist on the page:
// Wrong: Fake rating not visible on page
"aggregateRating": {
"ratingValue": "5",
"reviewCount": "9999"
}
Best Practices
- Match visible content - Structured data must reflect what users see
- Be specific - Use the most specific type (BlogPosting vs Article)
- Keep it updated - Update structured data when content changes
- Test regularly - Rich results can stop appearing if data becomes invalid
- Don't overdo it - Only add relevant schemas
Conclusion
Structured data is one of the highest-ROI SEO techniques. It's relatively easy to implement and can significantly improve how your pages appear in search results.
Key takeaways:
- Use JSON-LD format (Google's preference)
- Start with Organization, WebSite, and Article
- Validate with Google's Rich Results Test
- Monitor in Search Console
- Match structured data to visible content
Need to audit structured data across your site? Try Katsau's analyze endpoint — extract and validate JSON-LD from any URL.
Try Katsau API
Extract metadata, generate link previews, and monitor URLs with our powerful API. Start free with 1,000 requests per month.