📋 In This Tutorial
We will walk through the exact code patterns required to embed Schema.org JSON-LD markup across three major tech stacks: plain static HTML, modern React / Next.js applications, and WordPress content management systems.
Step 1: Where Should the JSON-LD Script Tag Live?
The W3C specification and Google Search documentation recommend placing your JSON-LD block inside the <head> section of your HTML document:
<head>
<title>My Article Title</title>
<meta name="description" content="..." />
<!-- Recommended: Place JSON-LD script inside <head> -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "My Article Title"
}
</script>
</head>Note: Search engines can also parse JSON-LD placed inside the <body> tag if your CMS restricts header modifications.
Step 2: Implementing in Plain HTML / Static Websites
If your website is built with vanilla HTML or a static site generator (e.g. Hugo, Jekyll, Eleventy), you can paste the generated block directly into your page template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Acme Corporation - Home</title>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Acme Corporation",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"sameAs": [
"https://twitter.com/acme",
"https://github.com/acme"
]
}
</script>
</head>
<body>
<h1>Welcome to Acme</h1>
</body>
</html>Step 3: Implementing in Next.js (App Router)
In modern Next.js using the App Router (app/ directory), you can render a <script> tag directly inside any server component using dangerouslySetInnerHTML to prevent double-escaping:
// app/blog/[slug]/page.tsx
export default async function BlogPostPage({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
const jsonLd = {
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: post.title,
description: post.excerpt,
datePublished: post.publishedAt,
author: {
"@type": "Person",
name: post.author.name,
},
};
return (
<>
{/* Inject Schema.org JSON-LD */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<main>
<h1>{post.title}</h1>
<p>{post.content}</p>
</main>
</>
);
}Because Next.js server components render to raw HTML on the server before reaching the client, Googlebot and AI crawlers immediately receive the fully serialized JSON-LD block without executing client JavaScript.
Step 4: Implementing in WordPress
In WordPress, there are three common methods to add JSON-LD markup:
- Using a Header Hook in
functions.php: Add the code to your child theme:add_action('wp_head', function() { if (is_front_page()) { echo '<script type="application/ld+json">' . json_encode([ '@context' => 'https://schema.org', '@type' => 'Organization', 'name' => get_bloginfo('name'), 'url' => home_url(), ]) . '</script>'; } }); - Using an Header/Footer Code Snippets Plugin: Paste the copied
<script type="application/ld+json">block directly into the plugin’s header injection box. - Using Dedicated SEO Plugins (RankMath, Yoast): Most major SEO plugins have schema modules, though they may limit customization of nested properties.
Step 5: Testing and Validating Your Schema
Never deploy schema markup without testing:
- Local Validation: Use Silixen’s Schema Markup Validator to check syntax, required properties, and ISO date formatting instantly in your browser.
- External Google Rich Results Test: Verify whether your live URL complies with Google-specific rich results guidelines.
- Schema.org Validator: Test official Schema.org microdata and JSON-LD conformity.
Ready to generate your schema markup?
Create valid, cleanly formatted JSON-LD for Articles, Organizations, Products, and Breadcrumbs in seconds: