What is Structured Data?
Structured data is a standardized format for providing information about a page and classifying its content. Search engines use this data to understand your content better and create rich snippets in search results.
Benefits of Structured Data
- Rich Snippets - Enhanced search result appearances
- Better SEO - Improved search engine understanding
- Voice Search - Better compatibility with voice assistants
- Knowledge Graph - Potential inclusion in Google's Knowledge Graph
- Social Sharing - Enhanced social media previews
Schema.org Vocabulary
Schema.org is a collaborative effort by major search engines to create a common vocabulary for structured data.
Common Schema Types
- Organization - Company/business information
- Person - Individual person details
- Product - Product information
- Article - Blog posts and articles
- Recipe - Cooking recipes
- Event - Events and occasions
- LocalBusiness - Local business information
- Review - Reviews and ratings
HTML Microdata
Microdata uses HTML attributes to embed structured data directly in your HTML.
Basic Microdata Syntax
html
<div itemscope itemtype="https://schema.org/Person">
<h1 itemprop="name">John Doe</h1>
<p>Email: <a itemprop="email" href="mailto:john@example.com">john@example.com</a></p>
<p>Phone: <span itemprop="telephone">+1-555-123-4567</span></p>
<p>Job Title: <span itemprop="jobTitle">Software Developer</span></p>
<div itemprop="address" itemscope itemtype="https://schema.org/PostalAddress">
<span itemprop="streetAddress">123 Main St</span><br>
<span itemprop="addressLocality">Anytown</span>,
<span itemprop="addressRegion">ST</span>
<span itemprop="postalCode">12345</span>
</div>
</div>
Product Microdata Example
html
<div itemscope itemtype="https://schema.org/Product">
<h1 itemprop="name">Wireless Bluetooth Headphones</h1>
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<img src="headphones.jpg" alt="Wireless Headphones" itemprop="url">
</div>
<p itemprop="description">
Premium wireless headphones with noise cancellation and 30-hour battery life.
</p>
<div itemprop="brand" itemscope itemtype="https://schema.org/Brand">
<span itemprop="name">TechAudio</span>
</div>
<div itemprop="offers" itemscope itemtype="https://schema.org/Offer">
<span itemprop="price" content="299.99">$299.99</span>
<meta itemprop="priceCurrency" content="USD">
<link itemprop="availability" href="https://schema.org/InStock">In Stock
<link itemprop="url" href="https://example.com/headphones">
</div>
<div itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">
<span itemprop="ratingValue">4.5</span> out of
<span itemprop="bestRating">5</span> stars
(<span itemprop="reviewCount">128</span> reviews)
</div>
<div itemprop="review" itemscope itemtype="https://schema.org/Review">
<div itemprop="author" itemscope itemtype="https://schema.org/Person">
<span itemprop="name">Sarah Johnson</span>
</div>
<div itemprop="reviewRating" itemscope itemtype="https://schema.org/Rating">
<span itemprop="ratingValue">5</span> out of
<span itemprop="bestRating">5</span> stars
</div>
<p itemprop="reviewBody">
Excellent sound quality and comfortable for long listening sessions.
</p>
<meta itemprop="datePublished" content="2024-01-15">
</div>
</div>
Article Microdata
html
<article itemscope itemtype="https://schema.org/BlogPosting">
<header>
<h1 itemprop="headline">10 Tips for Better Web Development</h1>
<p>
By <span itemprop="author" itemscope itemtype="https://schema.org/Person">
<span itemprop="name">Jane Smith</span>
</span>
</p>
<time itemprop="datePublished" datetime="2024-01-20T10:00:00Z">
January 20, 2024
</time>
<time itemprop="dateModified" datetime="2024-01-22T14:30:00Z" style="display:none;">
January 22, 2024
</time>
</header>
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<img src="web-development-tips.jpg" alt="Web Development Tips" itemprop="url">
<meta itemprop="width" content="1200">
<meta itemprop="height" content="630">
</div>
<div itemprop="articleBody">
<p itemprop="description">
Learn essential web development tips to improve your coding skills and build better websites.
</p>
<!-- Article content -->
<h2>1. Use Semantic HTML</h2>
<p>Semantic HTML elements provide meaning to your content...</p>
<!-- More content -->
</div>
<div itemprop="publisher" itemscope itemtype="https://schema.org/Organization">
<meta itemprop="name" content="Web Dev Blog">
<div itemprop="logo" itemscope itemtype="https://schema.org/ImageObject">
<meta itemprop="url" content="https://example.com/logo.png">
</div>
</div>
<meta itemprop="wordCount" content="1250">
<meta itemprop="timeRequired" content="PT5M">
</article>
JSON-LD (Recommended Approach)
JSON-LD (JavaScript Object Notation for Linked Data) is Google's preferred format for structured data.
Basic JSON-LD Structure
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "John Doe",
"email": "john@example.com",
"telephone": "+1-555-123-4567",
"jobTitle": "Software Developer",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "Anytown",
"addressRegion": "ST",
"postalCode": "12345",
"addressCountry": "US"
},
"url": "https://johndoe.example.com"
}
</script>
Product JSON-LD
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Wireless Bluetooth Headphones",
"description": "Premium wireless headphones with noise cancellation and 30-hour battery life.",
"image": [
"https://example.com/headphones-1.jpg",
"https://example.com/headphones-2.jpg",
"https://example.com/headphones-3.jpg"
],
"brand": {
"@type": "Brand",
"name": "TechAudio"
},
"sku": "TA-WH-001",
"gtin": "123456789012",
"offers": {
"@type": "Offer",
"price": "299.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://example.com/headphones",
"seller": {
"@type": "Organization",
"name": "TechStore"
},
"priceValidUntil": "2024-12-31"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.5,
"reviewCount": 128,
"bestRating": 5,
"worstRating": 1
},
"review": [
{
"@type": "Review",
"author": {
"@type": "Person",
"name": "Sarah Johnson"
},
"datePublished": "2024-01-15",
"reviewBody": "Excellent sound quality and comfortable for long listening sessions.",
"reviewRating": {
"@type": "Rating",
"ratingValue": 5,
"bestRating": 5
}
}
]
}
</script>
Article JSON-LD
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "10 Tips for Better Web Development",
"description": "Learn essential web development tips to improve your coding skills and build better websites.",
"image": {
"@type": "ImageObject",
"url": "https://example.com/web-development-tips.jpg",
"width": 1200,
"height": 630
},
"author": {
"@type": "Person",
"name": "Jane Smith",
"url": "https://example.com/author/jane-smith"
},
"publisher": {
"@type": "Organization",
"name": "Web Dev Blog",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
},
"datePublished": "2024-01-20T10:00:00Z",
"dateModified": "2024-01-22T14:30:00Z",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.com/web-development-tips"
},
"wordCount": 1250,
"timeRequired": "PT5M",
"articleSection": "Web Development",
"keywords": ["web development", "coding tips", "HTML", "CSS", "JavaScript"]
}
</script>
Local Business JSON-LD
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Restaurant",
"name": "Mario's Italian Kitchen",
"description": "Authentic Italian cuisine in the heart of downtown",
"image": "https://example.com/restaurant-photo.jpg",
"address": {
"@type": "PostalAddress",
"streetAddress": "456 Oak Street",
"addressLocality": "Downtown",
"addressRegion": "CA",
"postalCode": "90210",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": "34.0522",
"longitude": "-118.2437"
},
"url": "https://mariositalian.example.com",
"telephone": "+1-555-PIZZA-01",
"email": "info@mariositalian.example.com",
"openingHours": [
"Mo-Th 11:00-22:00",
"Fr-Sa 11:00-23:00",
"Su 12:00-21:00"
],
"servesCuisine": "Italian",
"priceRange": "$$",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.3,
"reviewCount": 156
},
"paymentAccepted": "Cash, Credit Card",
"currenciesAccepted": "USD"
}
</script>
Recipe JSON-LD
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Recipe",
"name": "Classic Chocolate Chip Cookies",
"description": "Soft and chewy chocolate chip cookies with a perfect golden edge.",
"image": [
"https://example.com/cookies-1.jpg",
"https://example.com/cookies-2.jpg"
],
"author": {
"@type": "Person",
"name": "Chef Maria"
},
"datePublished": "2024-01-15",
"prepTime": "PT15M",
"cookTime": "PT12M",
"totalTime": "PT27M",
"recipeCategory": "Dessert",
"recipeCuisine": "American",
"recipeYield": "24 cookies",
"keywords": "chocolate chip, cookies, dessert, baking",
"nutrition": {
"@type": "NutritionInformation",
"calories": "150 per cookie",
"fatContent": "7g",
"carbohydrateContent": "20g",
"proteinContent": "2g"
},
"recipeIngredient": [
"2 1/4 cups all-purpose flour",
"1 tsp baking soda",
"1 tsp salt",
"1 cup butter, softened",
"3/4 cup granulated sugar",
"3/4 cup packed brown sugar",
"2 large eggs",
"2 tsp vanilla extract",
"2 cups chocolate chips"
],
"recipeInstructions": [
{
"@type": "HowToStep",
"text": "Preheat oven to 375°F (190°C)."
},
{
"@type": "HowToStep",
"text": "Mix flour, baking soda and salt in bowl."
},
{
"@type": "HowToStep",
"text": "Beat butter, granulated sugar, brown sugar, eggs and vanilla extract until creamy."
},
{
"@type": "HowToStep",
"text": "Gradually beat in flour mixture. Stir in chocolate chips."
},
{
"@type": "HowToStep",
"text": "Drop rounded tablespoons of dough onto ungreased cookie sheets."
},
{
"@type": "HowToStep",
"text": "Bake 9 to 11 minutes or until golden brown. Cool completely."
}
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.8,
"reviewCount": 95
}
}
</script>
Event JSON-LD
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Event",
"name": "Web Development Conference 2024",
"description": "Join industry experts for the latest trends in web development, featuring workshops and keynote presentations.",
"image": "https://example.com/conference-banner.jpg",
"startDate": "2024-06-15T09:00:00-07:00",
"endDate": "2024-06-16T17:00:00-07:00",
"eventStatus": "https://schema.org/EventScheduled",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"location": {
"@type": "Place",
"name": "Tech Convention Center",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Conference Way",
"addressLocality": "San Francisco",
"addressRegion": "CA",
"postalCode": "94102",
"addressCountry": "US"
}
},
"organizer": {
"@type": "Organization",
"name": "WebDev Events",
"url": "https://webdevevents.com"
},
"offers": {
"@type": "Offer",
"price": "299",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://example.com/conference-tickets",
"validFrom": "2024-01-01T00:00:00-00:00"
},
"performer": [
{
"@type": "Person",
"name": "John Smith",
"jobTitle": "Senior Web Developer"
},
{
"@type": "Person",
"name": "Emily Johnson",
"jobTitle": "UX Designer"
}
]
}
</script>
Combining Multiple Schema Types
Sometimes you need to use multiple schema types on a single page:
html
<!-- Organization + Website -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "TechCorp Solutions",
"url": "https://example.com",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
},
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+1-555-123-4567",
"contactType": "customer service"
},
"sameAs": [
"https://facebook.com/techcorp",
"https://twitter.com/techcorp",
"https://linkedin.com/company/techcorp"
]
},
{
"@type": "WebSite",
"@id": "https://example.com/#website",
"url": "https://example.com",
"name": "TechCorp Solutions",
"publisher": {
"@id": "https://example.com/#organization"
},
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://example.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
]
}
</script>
Testing Structured Data
Google's Rich Results Test
html
<!-- Test your structured data at: https://search.google.com/test/rich-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 and classifying the page content."
}
},
{
"@type": "Question",
"name": "Why use JSON-LD over Microdata?",
"acceptedAnswer": {
"@type": "Answer",
"text": "JSON-LD is easier to implement, maintain, and doesn't clutter your HTML markup. It's Google's recommended format."
}
}
]
}
</script>
Schema Markup Validator
javascript
// Simple JavaScript validator for JSON-LD
function validateJSONLD(jsonldString) {
try {
const data = JSON.parse(jsonldString);
// Basic validation checks
const errors = [];
if (!data['@context']) {
errors.push('Missing @context property');
}
if (!data['@type']) {
errors.push('Missing @type property');
}
// Type-specific validation
if (data['@type'] === 'Product') {
if (!data.name) errors.push('Product must have a name');
if (!data.offers) errors.push('Product should have offers');
}
if (data['@type'] === 'Article') {
if (!data.headline) errors.push('Article must have a headline');
if (!data.author) errors.push('Article should have an author');
}
return {
valid: errors.length === 0,
errors: errors
};
} catch (e) {
return {
valid: false,
errors: ['Invalid JSON format: ' + e.message]
};
}
}
// Usage example
const testData = `{
"@context": "https://schema.org",
"@type": "Product",
"name": "Test Product"
}`;
const result = validateJSONLD(testData);
console.log('Validation result:', result);
Advanced Structured Data Patterns
Breadcrumb Navigation
html
<nav aria-label="Breadcrumb">
<ol itemscope itemtype="https://schema.org/BreadcrumbList">
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a itemprop="item" href="/">
<span itemprop="name">Home</span>
</a>
<meta itemprop="position" content="1">
</li>
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a itemprop="item" href="/products">
<span itemprop="name">Products</span>
</a>
<meta itemprop="position" content="2">
</li>
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<span itemprop="name">Headphones</span>
<meta itemprop="position" content="3">
</li>
</ol>
</nav>
<!-- JSON-LD equivalent -->
<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": "Products",
"item": "https://example.com/products"
},
{
"@type": "ListItem",
"position": 3,
"name": "Headphones"
}
]
}
</script>
Video Content
html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "How to Build a Website",
"description": "Complete tutorial on building a modern website from scratch using HTML, CSS, and JavaScript.",
"thumbnailUrl": "https://example.com/video-thumbnail.jpg",
"uploadDate": "2024-01-15T08:00:00Z",
"duration": "PT15M30S",
"contentUrl": "https://example.com/videos/website-tutorial.mp4",
"embedUrl": "https://example.com/embed/website-tutorial",
"author": {
"@type": "Person",
"name": "Web Developer Pro"
},
"publisher": {
"@type": "Organization",
"name": "Learn Web Dev",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
}
}
</script>
Common Mistakes and Best Practices
Don't Do This
html
<!-- Incorrect: Missing required properties -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"description": "Great product!"
}
</script>
<!-- Incorrect: Wrong data types -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Product Name",
"offers": {
"@type": "Offer",
"price": "$99.99",
"priceCurrency": "USD"
}
}
</script>
Do This Instead
html
<!-- Correct: All required properties included -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Awesome Product",
"description": "Great product with amazing features!",
"offers": {
"@type": "Offer",
"price": "99.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
}
</script>
Best Practices Checklist
- Use JSON-LD when possible (cleaner, easier to maintain)
- Include required properties for each schema type
- Use correct data types (numbers as numbers, not strings)
- Test regularly with Google's Rich Results Test
- Be specific - use the most specific schema type available
- Keep data accurate - match what's visible on the page
- Use structured data consistently across your site
Dynamic Structured Data with JavaScript
html
<script>
// Generate structured data dynamically
function generateProductSchema(product) {
const schema = {
"@context": "https://schema.org",
"@type": "Product",
"name": product.name,
"description": product.description,
"image": product.images,
"brand": {
"@type": "Brand",
"name": product.brand
},
"offers": {
"@type": "Offer",
"price": product.price.toString(),
"priceCurrency": product.currency,
"availability": product.inStock ?
"https://schema.org/InStock" :
"https://schema.org/OutOfStock"
}
};
// Add aggregateRating if reviews exist
if (product.reviews && product.reviews.length > 0) {
const totalRating = product.reviews.reduce((sum, review) => sum + review.rating, 0);
schema.aggregateRating = {
"@type": "AggregateRating",
"ratingValue": (totalRating / product.reviews.length).toFixed(1),
"reviewCount": product.reviews.length
};
}
return schema;
}
// Insert structured data into page
function addStructuredData(schema) {
const script = document.createElement('script');
script.type = 'application/ld+json';
script.textContent = JSON.stringify(schema, null, 2);
document.head.appendChild(script);
}
// Usage example
const productData = {
name: "Wireless Mouse",
description: "Ergonomic wireless mouse with precision tracking",
brand: "TechGear",
price: 49.99,
currency: "USD",
inStock: true,
images: ["https://example.com/mouse1.jpg"],
reviews: [
{ rating: 5, text: "Great mouse!" },
{ rating: 4, text: "Good value for money" }
]
};
const productSchema = generateProductSchema(productData);
addStructuredData(productSchema);
</script>