How to Add JSON-LD to a Page: Placement, Structure & Hands-on Steps
The previous article settled on JSON-LD. This one gets hands-on: add a piece of structured data to a page. The good news is that JSON-LD is the easiest of the three formats to pick up—it's just an independent piece of JSON inside a <script> tag, with no existing HTML to modify. This article covers placement, basic structure, field filling, multiple types coexisting, and complete hands-on steps.
Where to Place It#
JSON-LD is written inside a <script type="application/ld+json"> tag. This tag can go in the <head> or <body>; Google reads both.
- Recommended in
<head>: Keeps it centralized with SEO meta liketitleandcanonicalfor easy management. - In
<body>is fine too: For example, when output by a component/template in the content area. - The key is to land in the initial HTML: Best to output it on the server side and avoid relying on JavaScript rendering (see JavaScript SEO Basics for why).
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "How to Add JSON-LD to a Page"
}
</script>
type must be exactly application/ld+json; get it wrong and Google won't parse it. Also, JSON-LD cannot contain comments (JSON doesn't support // or /* */), and trailing commas aren't allowed—any of these will break parsing.Basic Structure Breakdown#
Every JSON-LD object has two essential "skeleton" fields; the rest are properties describing specific information.
| Field | Role | Value |
|---|---|---|
@context | Declares the vocabulary in use | Almost always "https://schema.org" |
@type | Declares what type of thing this is | e.g., Article, Product, FAQPage |
| Other properties | Describe the type's specific information | Depends on @type, e.g., headline, author |
@context: Tells the parser "interpret the following field names by schema.org's definitions." Just writehttps://schema.org.@type: Determines whether this object describes an article, a product, Q&A, etc. It also determines which fields are available and which are required.
Nested Objects & Data Types#
Property values aren't just strings—they can be numbers, arrays, or another object with a @type. For example, an article's author isn't a plain name but a Person or Organization object:
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "How to Do Keyword Research Well",
"image": "https://example.com/cover.webp",
"datePublished": "2026-06-24",
"author": {
"@type": "Person",
"name": "John Doe",
"url": "https://example.com/authors/john-doe"
},
"publisher": {
"@type": "Organization",
"name": "Example Media",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
}
}
| Value Type | How to Write | Example |
|---|---|---|
| Text | String | "headline": "Title" |
| Date | ISO 8601 string | "datePublished": "2026-06-24" |
| Number | Without quotes | "ratingValue": 4.8 |
| Multiple values | Array | "image": ["a.webp", "b.webp"] |
| Sub-object | Object with @type | "author": { "@type": "Person", ... } |
Required & Recommended Fields#
Each structured data type has Google-specified required and recommended fields. This is a key point many overlook:
- Required fields: Without them, the type can't earn rich results, and the testing tool will report an error outright.
- Recommended fields: Filling them in raises the probability of a rich result and the richness of its display; the testing tool usually flags these as warnings.
Field requirements differ greatly across types—you must consult the Google documentation page for the corresponding type. The specific fields for each type are covered one by one in this section's "Type Guide."
Multiple Types on One Page#
A page often needs multiple kinds of structured data. There are two ways to write it, and Google supports both:
Option 1: Multiple independent script tags (recommended)
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "Article", ... }
</script>
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "BreadcrumbList", ... }
</script>
Option 2: One array holding multiple types
<script type="application/ld+json">
[
{ "@context": "https://schema.org", "@type": "Article", ... },
{ "@context": "https://schema.org", "@type": "BreadcrumbList", ... }
]
</script>
Both have the same effect. Option 1 is recommended: one tag per type, so adding or removing a type doesn't affect the others, and troubleshooting is more intuitive.
Hand-written or Dynamically Generated#
A few fixed pages can have hand-written JSON-LD; but once pages multiply, generating via templates or programs becomes realistic.
| Method | Suitable For | Watch Out For |
|---|---|---|
| Hand-written | Few, fixed-structure pages | Mind JSON syntax; avoid typos |
| Template-generated | Static sites, SSG, CMS | Bind fields to content data sources |
| CMS plugin | WordPress etc. | Yoast, Rank Math auto-output |
| Server-side dynamic | Large dynamic sites | Ensure output lands in the initial HTML |
JSON.stringify) over hand-concatenating strings.The Most Important Principle: Match Visible Content#
This is the red line of structured data: the content JSON-LD describes must be content the user can actually see on the page.
- The marked-up title, author, date, price, and rating must all match the page's visible information.
- Don't mark up information that doesn't exist on the page (such as fabricated ratings, inflated prices, hidden keywords).
- This is an explicit Google requirement, and violating it can cause rich results to fail or even trigger a manual penalty.
The essence of structured data is translating "content already on the page" into a format machines can precisely understand, not adding information out of thin air. The complete guidelines and pitfalls are covered in this section's "Structured Data Guidelines & Common Pitfalls" article.
Complete Hands-on Steps#
- Determine the type: Decide which type the page content belongs to (Article for articles, FAQPage for Q&A, Product for products...).
- Check official field requirements: Look up the type's required and recommended fields in Google's docs.
- Write the JSON-LD: Fill in real data matching the visible content, minding JSON syntax.
- Place it in the page: Put it in
<head>inside a<script type="application/ld+json">tag, ensuring it's in the initial HTML. - Validate: Check for errors with Rich Results Test and the Schema Markup Validator (see the next article).
- Monitor after launch: Track status in Search Console's rich results report (see the related article in this section).
This Site's JSON-LD Practice#
The article you're reading has three independent JSON-LD blocks in its <head>:
<!-- 1. Article: describes the article itself -->
<script type="application/ld+json">{ "@type": "Article", ... }</script>
<!-- 2. BreadcrumbList: describes the breadcrumb path -->
<script type="application/ld+json">{ "@type": "BreadcrumbList", ... }</script>
<!-- 3. FAQPage: describes the FAQ at the end -->
<script type="application/ld+json">{ "@type": "FAQPage", ... }</script>
<head> (pure static output, no render delay). Every JSON-LD field strictly corresponds to visible page content—the breadcrumb is the navigation bar at the top, the FAQ is the Q&A at the end, and the title and date match the body. You can view this page's source to verify each one—this is the "practice what you preach" structured data implementation.Adding JSON-LD Checklist#
- script type is exactly application/ld+json
- Contains @context (https://schema.org) and @type
- Choose the right type and fill in its required fields
- Fill in recommended fields as much as possible to enrich it
- All field values match the page's visible content
- JSON syntax is correct (no comments, no trailing commas, proper escaping)
- Placed in the initial HTML in head (avoid depending on JS rendering)
- Multiple types use multiple independent script tags
- Validated and passing with Rich Results Test
- Monitored in Search Console after launch
Frequently Asked Questions#
Should JSON-LD go in the head or the body?
Either head or body works—Google can read both. It's recommended to place it in the <head> for centralized management, alongside other SEO tags like title and canonical. Google can also read JSON-LD injected dynamically by JavaScript during rendering, but watch out for render delay—the safest approach is to output the JSON-LD into the initial HTML on the server side.
Must the JSON-LD content match the page's visible content?
It must match. Google requires that the content described by structured data be content genuinely visible to users on the page. Marking up information that doesn't exist on the page in the JSON-LD (for example, a fabricated rating or a nonexistent price) violates the structured data guidelines and can cause rich results to be disabled or even trigger a manual penalty. Structured data is a "translation" of visible content, not adding information out of thin air.
Can a page have multiple JSON-LD tags?
Yes. A page can have multiple independent script tags of type application/ld+json, each describing a different type (like Article, BreadcrumbList, FAQPage). They don't interfere with each other. You can also put multiple types into an array output via a single script tag. Google supports both ways; writing them separately is usually clearer and easier to maintain.
Does adding JSON-LD guarantee a rich result will appear?
Not necessarily. Correct JSON-LD is a prerequisite for earning rich results, not a guarantee. Google comprehensively judges page quality, whether the content meets the display requirements of the corresponding type, whether it violates guidelines, and so on, then decides whether and when to show a rich result. Even with entirely correct markup, Google reserves the right not to display. Getting the markup right and passing validation with testing tools is what you can control.