JSON-LD (JSON for Linked Data) is a lightweight format used to share structured data across the web. It translates human-readable content into a machine-readable format that search engines and AI use to understand the specific meaning of a page.
Implementing this markup allows you to describe entities like people, events, recipes, and organizations, making your site eligible for enhanced search features.
What is JSON-LD?
JSON-LD is a method of encoding Linked Data using JSON. It is 100% compatible with existing JSON, meaning developers can use the format with various programming languages and databases without specialized software.
Unlike other formats that interleave data within HTML tags, JSON-LD exists as a standalone block of code. It uses a universal identifier mechanism to map property keys to full Internationalized Resource Indicators (IRIs), ensuring that a term like "name" is uniquely defined across the global web.
Why JSON-LD matters
For SEO practitioners, JSON-LD is the primary tool for securing "rich results" on search engine result pages (SERPs). These enhanced listings provide more interactive information to users and directly impact site performance metrics.
- Higher Interaction: [Rakuten observed that users spend 1.5x more time on pages with structured data] (Google Search Central).
- Increased Traffic: [The Food Network saw a 35% increase in visits after enabling search features for 80% of its pages] (Google Search Central).
- Improved Click-Through Rates: [Nestlé found that rich results in search drove an 82% higher click-through rate than standard results] (Google Search Central).
- Better Scaling: Because the markup is separate from UI code, it is easier to maintain and can be dynamically injected into a page via JavaScript or widgets.
How JSON-LD works
JSON-LD functions by building a "directed graph." In this model, the document is a node, and the keys (edges) connect it to other entities or values.
- The Context (@context): This maps short "terms" to the full URLs of a vocabulary (like Schema.org). Without this, a machine doesn't know if "name" refers to a person or a product.
- Node Identifiers (@id): These provide an unambiguous URL for an entity. If an entity lacks an
@id, it is treated as a "blank node." - Types (@type): This specifies what the object is (e.g., a "Recipe" or a "Person").
- Value Objects: These contain the actual data, such as strings, numbers, or dates, which are the leaf nodes of the graph.
Best practices
- Place markup in a script tag: Embed the code within a
<script type="application/ld+json">tag. This can go in either the<head>or the<body>of the HTML. - Prioritize accuracy over volume: It is more useful to provide a few complete and accurate recommended properties than to fill every field with badly formed or inaccurate data.
- Follow character limits: Ensure your strings are valid JSON. Special characters like
<should be escaped or scrubbed to prevent XSS vulnerabilities. - Include all required properties: Google requires specific fields for a page to be eligible for rich results. Check the latest documentation for your specific feature type.
- Test before deployment: Use tools like the Rich Results Test to validate syntax and see how the data will appear in search results.
Common mistakes
Mistake: Adding markup for information that is not visible to the user. Fix: Ensure all data in your JSON-LD accurately describes the content actually present on the page.
Mistake: Creating empty or blank pages just to hold structured data. Fix: Only place markup on pages where the specific information is displayed to visitors.
Mistake: Using invalid syntax or conflicting contexts. Fix: Use a debugger like the JSON-LD Playground to visualize the graph and find errors.
Mistake: Forgetting to update scripts after site templates change. Fix: Monitor Rich Result status reports in Search Console after deployment to catch breakages.
Examples
Example scenario: Describing a Person
This markup identifies an individual and connects them to a specific homepage using the Schema.org vocabulary.
{
"@context": "https://schema.org/",
"@type": "Person",
"name": "Jane Doe",
"url": "http://www.janedoe.com",
"image": "http://www.janedoe.com/photo.jpg"
}
Example scenario: Describing a Recipe
By using specific attributes, search engines can display the cook time and ingredients directly in search results.
{
"@context": "https://schema.org/",
"@type": "Recipe",
"name": "Classic Tomato Soup",
"author": {
"@type": "Person",
"name": "Chef Marco"
},
"cookTime": "PT30M",
"prepTime": "PT15M"
}
JSON-LD vs. Microdata
| Feature | JSON-LD | Microdata |
|---|---|---|
| Placement | Single <script> block |
Spread throughout HTML tags |
| Maintenance | High (isolated from UI) | Low (tied to HTML structure) |
| Dynamic Injection | Supported | Difficult to implement |
| Google Stance | Recommended format | Supported |
Rule of thumb: In most cases, use JSON-LD because it is easier to implement, maintain, and less likely to break when you change your site's design.
FAQ
What is the difference between @context and @type?
The @context tells the machine where to look for the definition of the terms used in the code. It acts as a map that connects short labels to global vocabularies. The @type tells the machine exactly what kind of thing you are describing, such as a "Book" or a "Movie."
Can I use multiple @contexts? Yes. Multiple contexts can be combined using an array. They are processed in order, meaning the last-defined context will win if there is a conflict between term definitions.
Does JSON-LD need to be in the head?
Not necessarily. While putting it in the <head> is common, Google can read JSON-LD data found in either the <head> or the <body> of an HTML page. This includes data that is dynamically injected into the contents by JavaScript or widgets.
How do I measure the success of JSON-LD? A common method is to perform a "before and after" test. Record performance for several months in Search Console using pages without markup. Add the markup, verify it is valid with the URL Inspection tool, and then monitor the Performance report filtered by "Search Appearance" to see the impact of rich results.
What are "blank nodes"?
A blank node is an entity that does not have a global URL identifier (it lacks an @id). In JSON-LD, these are assigned an identifier starting with _: to help the machine relate properties within the context of a single document.
What is the "expanded form" of JSON-LD?
Expanded form is the result of removing the @context and replacing all terms with their full IRIs. It makes the document consistently machine-readable but much more verbose and harder for humans to read.