Skip to main content

The fundamentals of structured data (JSON-LD / schema.org)

What is structured data

Structured data is markup that describes the content of a web page in a form that search engines can understand mechanically. Instead of relying on the natural language in the body text, it declares semantic information such as "what is the subject of this page / who is the provider / who is the target audience" in a separate layer.

Search engines (Google, Bing, etc.) cannot fully grasp the subject of a page from natural language processing of the body alone. By including structured data alongside it, you form a contract that says "this is the essence of this page" between the search engine and the content provider.

What you gain
  • "Rich results" (with images / review stars / breadcrumbs, etc.) are more likely to appear in search results
  • It is used as a source for knowledge panels (e.g., Organization markup affects how the logo and knowledge panel are displayed)
  • Voice search and AI assistants can extract information more easily
  • Search engines can more easily grasp the relationships between pages (organization → service → audience)

That said, "writing structured data" does not guarantee that rich results will appear. The official position is that it is up to Google's judgment. The details are covered in 02. Google guidelines.

There are three formats for structured data

There are mainly three formats for writing structured data.

FormatPlacementCharacteristics
JSON-LDA <script type="application/ld+json"> blockSeparate from the body HTML; easy to maintain
MicrodataAttributes on HTML elements (itemtype, itemprop)Embedded in the body; directly tied to visual elements
RDFaAttributes on HTML elements (typeof, property)Embedded in the body; more general-purpose

Of these, JSON-LD is what Google recommends. The main reason is that it can be completely separated from the body HTML, so you do not need to change your markup structure to meet SEO requirements, which makes it highly maintainable. The detailed rationale is covered in Chapter 02.

JSON-LD syntax

As the name suggests, JSON-LD is JSON-based, but it reinforces meaning with reserved keywords that begin with @.

Minimal example

{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Acme Workflow"
}
  • @context: specifies the vocabulary you use (where types and properties are defined). For schema.org, use "https://schema.org"
  • @type: what type this object is (e.g., WebPage, Service, Organization)
  • The other regular properties (name, description, url, etc.) are defined per type
Use https

In older samples you may see "@context": "http://schema.org", but the correct form today is https://schema.org. This is a result of schema.org moving to HTTPS. Both still work, but to avoid confusion, new implementations should standardize on https.

@id — a unique identifier for an object

When you handle multiple objects within a single JSON-LD, you use @id for cross-references. A URI serves as the identifier, and by convention it is expressed as a URL plus a fragment (#xxx).

{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Acme Inc.",
"url": "https://example.com/"
},
{
"@type": "WebPage",
"@id": "https://example.com/services/workflow/#webpage",
"name": "Acme Workflow",
"publisher": { "@id": "https://example.com/#organization" }
}
]
}

By referencing the Organization from publisher via @id, you can express the relationship without expanding the nesting. By convention, the URL in @id is made to correspond to the URL that represents that object, and the fragment identifies "that concept within the page."

Nesting and references

There are two ways to include an object inside another object.

Inline (nesting):

{
"@type": "WebPage",
"publisher": {
"@type": "Organization",
"name": "Acme Inc."
}
}

Reference (via @id):

{
"@type": "WebPage",
"publisher": { "@id": "https://example.com/#organization" }
}

When multiple pages reference the same Organization, the latter makes it easier to keep things consistent. Defining the Organization in one place across the whole site and referencing it from each page via @id is a design that wins on maintainability as the site grows.

schema.org Data Model

schema.org is a vocabulary that was founded by Google / Microsoft / Yahoo / Yandex and is now developed through an open community process centered on the W3C Schema.org Community Group. It defines a hierarchy of Types and Properties.

schema.org documentation

The official Schema.org Data Model (checked: 2026-05) explains the overall picture. This guide introduces only the key points.

The type hierarchy (inheritance)

schema.org types have a hierarchical structure. With Thing at the top, every type inherits from Thing.

For example, because WebPage inherits CreativeWork → Thing, it has properties derived from CreativeWork (author, datePublished, etc.) and properties derived from Thing (name, description, url, etc.).

Property ranges

Each property defines "what type of value it can take."

  • The range of Service.provider is Organization or Person
  • The range of WebPage.isPartOf is CreativeWork or URL (this guide specifies WebSite, a subtype of CreativeWork)
  • The range of Service.areaServed is one of AdministrativeArea / GeoShape / Place / Text

You can check ranges in the "Properties" section of each schema.org type page (e.g., Service).

Multiple inheritance and DataType

schema.org allows multiple inheritance (for example, LocalBusiness inherits from both Organization and Place). This lets you express entities that carry multiple contexts at once, but beginners are safer choosing types within the range of single inheritance.

Also, data types such as Text / Number / Boolean / Date live under DataType, and properties that take a String like name receive this Text as their value.

How to embed it in HTML

JSON-LD is embedded in HTML with a <script> tag.

<!DOCTYPE html>
<html lang="ja">
<head>
<title>Acme Workflow</title>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Acme Workflow",
"description": "A task management SaaS for operations staff"
}
</script>
</head>
<body>
...
</body>
</html>
Best practices for placement
  • It works either inside <head> or inside <body> (Google reads both)
  • You may place multiple <script type="application/ld+json"> blocks on one page (but be careful about duplicating the subject; details are in Chapter 03)
  • For frameworks like React / Vue / Next.js, follow each framework's recommended method (Next.js renders a native <script> tag inside the layout / page component; Nuxt uses useHead, etc.). Note that next/script's <Script> is meant for executable JS and is officially documented as unsuitable for JSON-LD

Dynamic generation vs. static generation

The embedding strategy changes depending on the type of site.

  • Static sites: write it directly in the HTML, or generate it at build time
  • SSR (Next.js / Nuxt): generate it server-side and include it in the initial HTML (so Google can read it even before JavaScript runs)
  • CSR only: generate it with client-side JavaScript. Google reads HTML after JS runs too, but since it is more susceptible to rendering delays, SSR is recommended

This guide stays framework-independent and focuses on the content (structure) of the JSON-LD. For head-injection implementations specific to your language, refer to each framework's documentation.

What's next

So far we have covered the overall picture of structured data and the basics of JSON-LD syntax. The next chapter, 02. Google guidelines, covers the policies Google defines and the rationale for why JSON-LD is recommended. Be sure to read it before you start implementing.