You have probably seen search results that show more than a blue link and a snippet: a publish date, an author, or a breadcrumb trail of the site’s hierarchy. These are called rich results, and the raw material behind them is structured data embedded in the page. This post covers JSON-LD, today’s most common format: what it describes and how to verify it, using the implementation on this blog (wpmm.jp/blog and en.wpmm.jp/blog) as the example.
Note: structured data is an annotation that presents a page’s meaning in a machine-readable form. Writing it does not guarantee any particular display. It is a hint that helps a search engine understand the content.
What Problem It Addresses
A person looking at a page can tell “this is an article, published on this date, by this author.” A search engine has to infer that from markup and layout. Is a date-like string the publish date or the last-updated date? Is a name-like string the author or a quoted source? Guessing from context leaves room for error.
Structured data reduces that room. You add labels that say “this is the publish date” and “this is the author” as separate data. The vocabulary comes from a shared dictionary, schema.org, which defines types such as BlogPosting, Organization, and BreadcrumbList.
Three Formats, and Why JSON-LD Is Easier to Maintain
| Format | Where it lives | Trait |
|---|---|---|
| Microdata | Attributes on existing HTML tags | Mixed into display markup, so template changes get entangled |
| RDFa | Attributes on existing HTML tags | Same |
| JSON-LD | A standalone <script> block |
Separate from display markup; data can be output as one unit |
JSON-LD is placed as a script tag, typically in the <head>:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Article title",
"datePublished": "2026-09-21T08:00:00+09:00",
"author": { "@type": "Person", "name": "Author name" }
}
</script>
It leaves the visible HTML untouched. For whoever maintains a theme, that means display changes and data management can be reasoned about separately.
The Few Symbols Worth Knowing
@context: which vocabulary is in use, almost alwayshttps://schema.org@type: what kind of thing the data describes (BlogPosting,Organization, and so on)@id: an identifier, usually URL-shaped, used to reference the data from elsewhere
@id matters when several pieces of data need to connect. Instead of repeating the publisher’s full details inside every article, you can point to it by @id.
This Blog’s Implementation: One @graph
The wpmm-blog theme outputs a single JSON-LD block in each page’s <head>. Its body is a @graph array, which bundles several items together. On an article page it holds:
| Type | Role |
|---|---|
Organization |
The publishing organization (name, URL, logo) |
WebSite |
The blog site itself, including its language |
BreadcrumbList |
The hierarchy, such as Home → Category → Article |
BlogPosting |
The article: headline, published and modified dates, author, category |
Here @id earns its keep. The organization is written once as an Organization, and both WebSite and BlogPosting refer to it through publisher by @id. Because the publisher’s details live in one place, changing them does not mean editing several spots.
// Simplified pseudocode
$graph[] = [ '@type' => 'Organization', '@id' => $base . '#organization', /* name, url, logo */ ];
$graph[] = [ '@type' => 'BlogPosting', '@id' => $permalink . '#blogposting',
'publisher' => [ '@id' => $base . '#organization' ], /* headline, dates, ... */ ];
echo '<script type="application/ld+json">';
echo wp_json_encode( [ '@context' => 'https://schema.org', '@graph' => $graph ],
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
echo '</script>';
The output goes through PHP’s wp_json_encode(), which produces correctly escaped JSON. A title containing quotes or special characters cannot break the block. The “escape on output” idea from the earlier escaping post applies to JSON as well: assembling JSON by string concatenation means a single stray quote can invalidate the whole block.
Dates are emitted in ISO 8601 with a timezone (for example via get_the_date('c')) rather than in a human-facing format. Structured data wants values a machine can interpret without guessing.
Match What the Page Actually Shows
The core rule is to keep structured data consistent with what the page displays. If the headline or date in the data differs from what appears on screen, a search engine sees an inconsistency, which can reduce trust in the data as a whole.
On this blog, the BlogPosting headline, dates, and author are all generated from the article’s own data. The visible page and the structured data do not keep separate copies of a value, so they are less likely to drift apart.
Verifying After Publishing
Like hreflang, JSON-LD is invisible on the rendered page. A missing block or a syntax error is easy to miss. Options for checking:
- View the page source and search for
application/ld+jsonto confirm the block exists - Pass the extracted JSON through a parser (for example
python3 -m json.tool) to confirm the syntax is valid - Use a search engine’s structured data testing tool to check types and required fields
On this blog, the SEO check script audit.py extracts the JSON-LD block from a page’s HTML and tries to parse it. If parsing fails it prints “PARSE ERROR”; if the block is absent it prints “MISSING”; otherwise it lists the types found (Organization / WebSite / BreadcrumbList / BlogPosting) along with the headline, dates, and author. Catching syntax errors and omissions mechanically is less error-prone than reading every field by eye after each publish.
Common Pitfalls
- JSON syntax errors: a trailing comma or unclosed quote makes the whole block unreadable. Generate JSON from arrays with an encoder instead of concatenating strings
- Data that differs from the page: including information not shown, or a date that does not match
- Inconsistent date formats: use ISO 8601 rather than display formats
- Duplicated definitions: writing organization details in several places and updating only one. Consolidate with
@id - Expecting a guaranteed display change: structured data is a hint; whether a rich result appears is up to the search engine
Summary
JSON-LD attaches meaning to a page’s content in a machine-readable form. Because it lives in a <script> block separate from display markup, a theme can manage it in one place. The essentials are choosing the right schema.org types, consolidating shared information with @id, keeping the data consistent with what the page shows, and checking for syntax errors and omissions after publishing.
Next up: OGP, the mechanism behind the card shown when a page is shared on social networks.