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.
- "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.,
Organizationmarkup 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.
| Format | Placement | Characteristics |
|---|---|---|
| JSON-LD | A <script type="application/ld+json"> block | Separate from the body HTML; easy to maintain |
| Microdata | Attributes on HTML elements (itemtype, itemprop) | Embedded in the body; directly tied to visual elements |
| RDFa | Attributes 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
httpsIn 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.
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.providerisOrganizationorPerson - The range of
WebPage.isPartOfisCreativeWorkorURL(this guide specifiesWebSite, a subtype ofCreativeWork) - The range of
Service.areaServedis one ofAdministrativeArea/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>
- 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 usesuseHead, etc.). Note thatnext/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.