JSON-LD Structured Data: Complete Implementation Guide
Master JSON-LD structured data implementation. Learn schema types, validation, and best practices for rich results.
Introduction
JSON-LD (JavaScript Object Notation for Linked Data) is the recommended format for structured data. This comprehensive guide teaches you how to implement JSON-LD to help search engines better understand your content and enable rich results.
What is JSON-LD?
JSON-LD is a method of encoding Linked Data using JSON. It's the Google-recommended format for structured data because it's:
- Easy to implement - Just add a script tag
- Non-intrusive - Separated from HTML content
- Scalable - Simple to maintain and update
- Flexible - Can be injected dynamically
Basic JSON-LD Structure
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Article Title",
"author": {
"@type": "Person",
"name": "Author Name"
}
}
</script>
Essential Schema Types
1. Organization Schema
Every website should have Organization schema:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Company Name",
"url": "https://www.example.com",
"logo": "https://www.example.com/logo.png",
"description": "Company description",
"sameAs": [
"https://twitter.com/company",
"https://linkedin.com/company/company",
"https://facebook.com/company"
],
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+1-555-555-5555",
"contactType": "Customer Service",
"availableLanguage": "English"
},
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "City",
"addressRegion": "State",
"postalCode": "12345",
"addressCountry": "US"
}
}
</script>
2. Article Schema
For blog posts and news articles:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Article Title Goes Here",
"image": "https://www.example.com/article-image.jpg",
"author": {
"@type": "Person",
"name": "Author Name"
},
"publisher": {
"@type": "Organization",
"name": "Publisher Name",
"logo": {
"@type": "ImageObject",
"url": "https://www.example.com/logo.png"
}
},
"datePublished": "2025-01-15",
"dateModified": "2025-01-15",
"description": "Article description that appears in search results"
}
</script>
3. Product Schema
For e-commerce products:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Product Name",
"image": [
"https://www.example.com/product-1.jpg",
"https://www.example.com/product-2.jpg"
],
"description": "Product description",
"sku": "PRODUCT-SKU",
"brand": {
"@type": "Brand",
"name": "Brand Name"
},
"offers": {
"@type": "Offer",
"url": "https://www.example.com/product",
"priceCurrency": "USD",
"price": "99.99",
"priceValidUntil": "2025-12-31",
"availability": "https://schema.org/InStock",
"seller": {
"@type": "Organization",
"name": "Seller Name"
}
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"reviewCount": "150"
}
}
</script>
4. Local Business Schema
For local businesses with physical locations:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"@id": "https://www.example.com#business",
"name": "Business Name",
"image": "https://www.example.com/business.jpg",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "City",
"addressRegion": "State",
"postalCode": "12345",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": "40.7128",
"longitude": "-74.0060"
},
"url": "https://www.example.com",
"telephone": "+1-555-555-5555",
"openingHoursSpecification": {
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "09:00",
"closes": "17:00"
},
"priceRange": "$$"
}
</script>
5. Breadcrumb Schema
For breadcrumb navigation in search results:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://www.example.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "Category",
"item": "https://www.example.com/category"
},
{
"@type": "ListItem",
"position": 3,
"name": "Product",
"item": "https://www.example.com/category/product"
}
]
}
</script>
6. FAQ Schema
For FAQ pages:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is the question?",
"acceptedAnswer": {
"@type": "Answer",
"text": "This is the answer to the question."
}
},
{
"@type": "Question",
"name": "Another question?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Another answer."
}
}
]
}
</script>
7. Review Schema
For product or service reviews:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Product Name",
"review": [
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
},
"author": {
"@type": "Person",
"name": "Reviewer Name"
},
"reviewBody": "Review text here."
}
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "250"
}
}
</script>
8. Video Object Schema
For video content:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "Video Title",
"description": "Video description",
"thumbnailUrl": "https://www.example.com/thumbnail.jpg",
"uploadDate": "2025-01-15",
"duration": "PT1M30S",
"contentUrl": "https://www.example.com/video.mp4",
"embedUrl": "https://www.example.com/embed/video",
"interactionStatistic": {
"@type": "InteractionCounter",
"interactionType": {
"@type": "WatchAction"
},
"userInteractionCount": 15000
}
}
</script>
9. Event Schema
For events and event listings:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Event",
"name": "Event Name",
"startDate": "2025-06-15T19:00",
"endDate": "2025-06-15T22:00",
"location": {
"@type": "Place",
"name": "Venue Name",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "City",
"addressRegion": "State",
"postalCode": "12345",
"addressCountry": "US"
}
},
"image": "https://www.example.com/event.jpg",
"description": "Event description",
"offers": {
"@type": "Offer",
"url": "https://www.example.com/tickets",
"price": "49.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "2025-01-01"
},
"organizer": {
"@type": "Organization",
"name": "Organizer Name",
"url": "https://www.example.com"
}
}
</script>
10. HowTo Schema
For how-to guides and tutorials:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "How to Do Something",
"image": "https://www.example.com/howto.jpg",
"estimatedCost": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": "50"
},
"totalTime": "PT30M",
"supply": [
{
"@type": "HowToSupply",
"name": "Supply 1"
}
],
"tool": [
{
"@type": "HowToTool",
"name": "Tool 1"
}
],
"step": [
{
"@type": "HowToStep",
"name": "Step 1",
"text": "Step 1 instructions",
"image": "https://www.example.com/step1.jpg"
},
{
"@type": "HowToStep",
"name": "Step 2",
"text": "Step 2 instructions"
}
]
}
</script>
Implementation Best Practices
1. Validation
Always validate your structured data:
Tools:
- Google Rich Results Test
- Schema Markup Validator
- Google Search Console
2. Common Mistakes to Avoid
- [ ] Syntax errors - Missing commas, brackets
- [ ] Invalid dates - Wrong ISO 8601 format
- [ ] Missing required fields - Each type has required properties
- [ ] Inconsistent data - Schema data doesn't match page content
- [ ] Duplicate schemas - Multiple schemas for same entity
- [ ] URL errors - Non-canonical URLs, invalid URLs
3. Dynamic Implementation
Generate JSON-LD dynamically:
React/Next.js example:
import Head from "next/head";
function ArticlePage({ article }) {
const structuredData = {
"@context": "https://schema.org",
"@type": "Article",
headline: article.title,
datePublished: article.publishedAt,
author: {
"@type": "Person",
name: article.author.name,
},
};
return (
<>
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(structuredData),
}}
/>
</Head>
{/* Article content */}
</>
);
}
4. Placement Guidelines
- Place JSON-LD in the
<head>section when possible - Can be placed in
<body>if needed - Only one script tag per entity
- Don't duplicate schema already present
Rich Result Opportunities
| Schema Type | Rich Result | | ------------- | ---------------------------------------- | | Article | Top stories carousel | | Product | Product information, price, availability | | Review | Star ratings | | LocalBusiness | Knowledge panel, local pack | | Event | Event listings | | FAQ | FAQ accordion in results | | HowTo | Rich step-by-step display | | Breadcrumb | Breadcrumb in results | | Video | Video thumbnail, duration | | Recipe | Recipe card with ratings |
Advanced Techniques
1. Multiple Schema Types
Combine schema types:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.example.com/#organization",
"name": "Company Name"
},
{
"@type": "WebSite",
"@id": "https://www.example.com/#website",
"url": "https://www.example.com",
"publisher": {
"@id": "https://www.example.com/#organization"
}
},
{
"@type": "Article",
"@id": "https://www.example.com/article#article",
"headline": "Article Title",
"publisher": {
"@id": "https://www.example.com/#organization"
}
}
]
}
</script>
2. Conditional Schema
Include schema based on content:
// Only include review schema if reviews exist
const structuredData = {
"@context": "https://schema.org",
"@type": "Product",
name: product.name,
...(product.reviews && {
aggregateRating: {
"@type": "AggregateRating",
ratingValue: product.rating,
reviewCount: product.reviewCount,
},
}),
};
3. Nested References
Use @id for referencing:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.example.com/#org",
"name": "Company Name"
},
{
"@type": "Article",
"publisher": {
"@id": "https://www.example.com/#org"
}
}
]
}
</script>
Testing and Monitoring
Test Before Deploying
- Use Rich Results Test
- Check in Schema Validator
- Preview in search results
- Monitor Search Console
Monitor Performance
After implementation, track:
- [ ] Rich result impressions
- [ ] Rich result clicks
- [ ] CTR improvement
- [ ] Ranking changes
- [ ] Structured data errors in Search Console
Conclusion
JSON-LD structured data is a powerful tool for improving how your content appears in search results. Start with essential schemas (Organization, Article, Breadcrumb) and expand to more advanced types as needed.
Remember: structured data helps search engines understand your content, but it doesn't guarantee rich results. Your content still needs to be high-quality and relevant.
Scan your website to check for existing structured data and get recommendations for improvement.