Schema Markup Tutorial: Add JSON-LD to Any Website (Step-by-Step)
Last Updated: February 25, 2026 · 15 min read
Schema markup is the layer of code that transforms an ordinary search result into a rich result with star ratings, images, prices, or FAQ dropdowns. This tutorial walks through every step — from understanding what schema is to deploying validated JSON-LD across HTML, WordPress, Shopify, and Next.js.
✅ What you'll achieve
By the end of this tutorial you will have working, validated schema markup deployed on a real page and eligible for rich results in Google Search.
Part 1: Understand What You're Adding
Schema markup is a JSON block placed inside a <script type="application/ld+json"> tag. It is invisible to visitors but readable by Google. Here is the minimal structure all schema markup follows:
<script type="application/ld+json">
{
"@context": "https://schema.org", ← always this, always
"@type": "Article", ← what kind of thing this is
"headline": "My Article Title", ← properties that describe it
"datePublished": "2026-02-25"
}
</script>@contextAlways "https://schema.org" — tells Google which vocabulary you're using
@typeThe type of thing (Article, Product, Recipe, FAQPage, etc.)
propertiesThe specific facts you're declaring (name, price, datePublished, etc.)
Part 2: Pick Your Schema Type
Match the schema type to your page content:
| Page type | Schema type | Rich result unlocked |
|---|---|---|
| Blog post / article | Article | Article card, Top Stories |
| Product page | Product + Offer | Price, stars, availability |
| Recipe | Recipe | Recipe card with image & time |
| FAQ section | FAQPage | Expandable Q&A dropdowns |
| How-to guide | HowTo | Numbered step previews |
| Local business | LocalBusiness subtype | Knowledge Panel, Maps |
| Event | Event | Event carousel listing |
| Job listing | JobPosting | Google Jobs listing |
| Video | VideoObject | Video thumbnail + duration |
Part 3: Write Your First Schema
Let's add Article schema to a blog post. Fill in your own values where you see placeholders:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "REPLACE: Your article title (max 110 chars)",
"datePublished": "REPLACE: 2026-02-25T09:00:00Z",
"dateModified": "REPLACE: 2026-02-25T09:00:00Z",
"author": {
"@type": "Person",
"name": "REPLACE: Your Name",
"url": "REPLACE: https://yoursite.com/about"
},
"publisher": {
"@type": "Organization",
"name": "REPLACE: Site Name",
"logo": {
"@type": "ImageObject",
"url": "REPLACE: https://yoursite.com/logo.png"
}
},
"image": "REPLACE: https://yoursite.com/article-image.jpg",
"description": "REPLACE: 1-2 sentence summary of the article."
}
</script>Part 4: Validate Before Deploying
Copy your JSON-LD block (just the JSON, not the <script> tags)
Go to SchemaValidator.org → paste into the code input
Fix all red errors. Common ones: missing required field, invalid date format, empty string value
Address amber warnings (missing recommended properties like image, description)
Once error-free, proceed to deployment
Part 5: Add to Your Platform
Plain HTML
Paste the <script> block inside the <head> or just before </body>:
<html>
<head>
<title>My Article</title>
<script type="application/ld+json">
{ ...your schema here... }
</script>
</head>
<body>...</body>
</html>WordPress (without a plugin)
Add to your theme's functions.php:
function add_article_schema() {
if ( is_single() ) {
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'Article',
'headline' => get_the_title(),
'datePublished' => get_the_date('c'),
'dateModified' => get_the_modified_date('c'),
'author' => array(
'@type' => 'Person',
'name' => get_the_author(),
),
);
echo '<script type="application/ld+json">'
. wp_json_encode($schema) . '</script>';
}
}
add_action( 'wp_head', 'add_article_schema' );Next.js (App Router)
// app/blog/[slug]/page.tsx
export default function BlogPost({ post }) {
const schema = {
"@context": "https://schema.org",
"@type": "Article",
"headline": post.title,
"datePublished": post.publishedAt,
"author": { "@type": "Person", "name": post.author }
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
<article>...</article>
</>
);
}Shopify
Edit your theme's product.liquid or article.liquid:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "{{ product.title | json }}",
"description": "{{ product.description | strip_html | json }}",
"image": "{{ product.featured_image | img_url: '1024x' }}",
"offers": {
"@type": "Offer",
"price": "{{ product.price | money_without_currency }}",
"priceCurrency": "{{ shop.currency }}",
"availability": "{% if product.available %}
https://schema.org/InStock
{% else %}
https://schema.org/OutOfStock
{% endif %}"
}
}
</script>Part 6: Confirm It's Working
🔍 View page source
Right-click → View Page Source → Ctrl+F "application/ld+json". If you see your schema, the <script> block is rendering server-side (correct). If you can't find it in source, it is being injected by JavaScript only — fix this.
🔍 Google Rich Results Test
Paste your page URL at search.google.com/test/rich-results. You should see your schema type detected. If not shown, the page may not be publicly accessible or the schema has a rendering issue.
🔍 Google Search Console
After 1–2 weeks post-deploy, check GSC Enhancements. You'll see your schema types listed with valid/error counts. This is your long-term monitoring dashboard.
Frequently Asked Questions
Do I need to add schema markup to every page?▼
No. Prioritise pages that stand to gain the most from rich results: product pages, recipe pages, FAQ sections, article pages, and local business pages. Adding schema to pages with thin or irrelevant content provides limited benefit.
What happens if I have errors in my schema markup?▼
Errors prevent Google from generating rich results for that page. Warnings (missing recommended fields) allow the schema to be processed but may reduce rich result quality. Always fix all errors before deploying.
How long until schema markup shows as rich results in Google?▼
Google typically crawls and processes schema within days to a few weeks of deployment. Rich results then appear when Googlebot recrawls the page and confirms the schema is valid. Monitor via Google Search Console Enhancements tab.
Can I add multiple schema types to one page?▼
Yes — this is normal and encouraged. Use separate <script type="application/ld+json"> blocks for each schema type. Common combinations: Article + BreadcrumbList + Organization, or Product + BreadcrumbList + FAQPage.
Does schema markup directly improve Google rankings?▼
Not directly. Schema is not a confirmed direct ranking factor. However, rich results dramatically improve click-through rates (often +20–50%), which increases traffic and sends positive user-behaviour signals to Google.
Is it safe to copy schema templates from this tutorial?▼
Yes, but replace all placeholder values with your actual content. Using real, accurate data is essential — Google’s spam policies explicitly prohibit misleading or inaccurate structured data.
What is the minimum viable schema I should add to a new site?▼
Start with: Organization schema (sitewide), BreadcrumbList on all pages, and the primary content type (Article, Product, LocalBusiness, etc.) on each relevant page. These three cover most common rich result opportunities.
Do I need a plugin or CMS tool to add schema markup?▼
No. Schema is just a JSON block in a script tag — you can add it directly to HTML, PHP, or any template. Plugins (Yoast, RankMath) automate generation for WordPress but are not required for non-WordPress sites.
Ready to Validate Your Schema?
Paste your JSON-LD and get an instant report — free, no login required.
Validate Schema Markup →Related Guides
What is Schema.org?
The vocabulary behind all structured data
What is JSON-LD?
The format used to write structured data
JSON-LD Generator Guide
Tools to generate schema markup automatically
Schema Markup Checker
How to validate and debug your schema
Google Rich Results Guide
Which schema types unlock rich results
Schema Markup Audit
Audit all schema across your entire site