Structured Data · Basics Article 3

How to Add JSON-LD to a Page: Placement, Structure & Hands-on Steps

~15 min read Updated 2026-06-24 MagicSEO Editors · Human Reviewed Structured Data

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 like title and canonical for 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).
Minimal usable example
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "How to Add JSON-LD to a Page"
}
</script>
Get the type Right, No Commentstype 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.

FieldRoleValue
@contextDeclares the vocabulary in useAlmost always "https://schema.org"
@typeDeclares what type of thing this ise.g., Article, Product, FAQPage
Other propertiesDescribe the type's specific informationDepends on @type, e.g., headline, author
  • @context: Tells the parser "interpret the following field names by schema.org's definitions." Just write https://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:

Nested object example
{
  "@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 TypeHow to WriteExample
TextString"headline": "Title"
DateISO 8601 string"datePublished": "2026-06-24"
NumberWithout quotes"ratingValue": 4.8
Multiple valuesArray"image": ["a.webp", "b.webp"]
Sub-objectObject 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."

Defer to Official Docsschema.org defines all possible fields for a type, but the fields Google actually uses for rich results are a subset. To judge "which fields are useful to Google and which are required," consult the Google Search Central structured data documentation, not just schema.org.

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)

Separate, clear, easy to maintain
<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

Single script, array form
<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.

MethodSuitable ForWatch Out For
Hand-writtenFew, fixed-structure pagesMind JSON syntax; avoid typos
Template-generatedStatic sites, SSG, CMSBind fields to content data sources
CMS pluginWordPress etc.Yoast, Rank Math auto-output
Server-side dynamicLarge dynamic sitesEnsure output lands in the initial HTML
Escape Dynamic ValuesWhen field values come from content (titles, descriptions, etc.), if the text contains double quotes, backslashes, or newlines, you must JSON-escape them or you'll break the JSON structure. When generating with code, prefer the language's built-in JSON serializer (like 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#

  1. Determine the type: Decide which type the page content belongs to (Article for articles, FAQPage for Q&A, Product for products...).
  2. Check official field requirements: Look up the type's required and recommended fields in Google's docs.
  3. Write the JSON-LD: Fill in real data matching the visible content, minding JSON syntax.
  4. Place it in the page: Put it in <head> inside a <script type="application/ld+json"> tag, ensuring it's in the initial HTML.
  5. Validate: Check for errors with Rich Results Test and the Schema Markup Validator (see the next article).
  6. 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>:

The three tags actually used on this page
<!-- 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>
Site ExampleAll MagicSEO articles use the "multiple independent script tags" approach: Article + BreadcrumbList + FAQPage, each in its own tag, all written into the initial HTML of <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.