# What Is JSON-LD and How It Is Used on a Product Page

> What JSON-LD is, what @context, @type, @id and @graph mean, why Google recommends it and how to find and check the block on your product page.

URL: https://clione.ai/glossary/json-ld/
Lang: en

If you open the source code of a [product page](/glossary/product-page/) and search for `application/ld+json`, what you find is JSON-LD: **a block of text that describes the page for machines, separate from what the customer sees**. JSON-LD is the format, the way of writing; the words it carries (product, price, brand) belong to [Schema.org](/glossary/schema-org/), and together they make up the page's [structured data](/glossary/structured-data/). It matters to you because it is the format Google recommends, including for pages that aim for [rich results](/glossary/rich-results/), and because, being separate, it is easy for it to say one thing while the page says another.

## How it works

JSON-LD is a W3C specification. Its current version, JSON-LD 1.1, defines it as a JSON-based format to serialize Linked Data, designed to fit into systems that already use JSON, and it has been a **W3C Recommendation since July 16, 2020**. It is a superset of version 1.0, from January 2014: everything that one allowed is still there.[^w3c-json-ld11] The community site presents it under its long name: _JSON for Linking Data_.[^json-ld-org]

A JSON-LD document is plain JSON with a few keywords that start with an at sign. The four you will see in a store:[^w3c-json-ld11]

- **`@context`**: the rules for interpreting the document. In practice, `"@context": "https://schema.org"` says that the words that follow are Schema.org's.
- **`@type`**: the type of what is being described, for example `Product`.
- **`@id`**: a unique identifier for the node, usually a web address (an IRI). It is what lets another block refer to that same product without repeating it; it has its own entry, the [`@id` identifier](/glossary/id-json-ld/).
- **`@graph`**: used to express a graph, several nodes in a single block. The entry on [`@graph`](/glossary/graph/) explains it.

On a web page, the block goes inside a `<script type="application/ld+json">` element.[^w3c-json-ld11] Google accepts that element in both the `<head>` and the `<body>`, and of the three formats it supports (JSON-LD, [microdata](/glossary/microdata/) and [RDFa](/glossary/rdfa/)) **it recommends JSON-LD whenever your site allows it, because it is the easiest to implement and maintain at scale and the least prone to errors**.[^google-sd-intro]

The block can arrive written into the HTML the server sends or be added later with JavaScript. Google can process structured data that is in the DOM when it renders the page, but it warns that **dynamically generated markup can make Shopping crawls less frequent and less reliable**, a problem for what changes fast, like [price and availability](/glossary/price-and-availability/).[^google-js-sd] If your theme or an app injects the block with JavaScript, the entry on [JavaScript rendering](/glossary/javascript-rendering/) explains what that implies.

The format is still alive. The W3C's JSON-LD working group has a mandate from January 6, 2026 to January 31, 2028 to publish JSON-LD 1.2, with the recommendation expected for the fourth quarter of 2027, and it commits that **any document valid in JSON-LD 1.1 will remain valid in 1.2**.[^w3c-json-ld-charter] What you publish today in 1.1 will not need rewriting because of the version change.

## In a store

A product page's block, reduced to the essentials. **Fictitious example**: the store, the product, the address and the price are made up, and the block only says what that imaginary page shows on screen.

```html
<script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Product",
    "@id": "https://www.example.com/calella-linen-shirt#product",
    "name": "Calella linen shirt, blue",
    "image": "https://www.example.com/img/calella-blue.jpg",
    "sku": "CAL-BL-M",
    "brand": { "@type": "Brand", "name": "Calella" },
    "offers": {
      "@type": "Offer",
      "price": "39.90",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock",
      "url": "https://www.example.com/calella-linen-shirt"
    }
  }
</script>
```

It reads top to bottom. `@context` sets the vocabulary. `@type` says it is a product, the [Product](/glossary/product-schema/) type. `@id` gives it a stable name that other blocks on the page can point to. The properties that follow are the vocabulary's, and `offers` opens a second, nested node, of type [Offer](/glossary/offer-schema/), with the price, the currency and the availability. Notice the price, with a decimal point, no symbol and the currency in its own property: the Offer entry explains why it is written that way.

A real page usually carries more than one node: the organization, the website, the [breadcrumbs](/glossary/breadcrumbs/) and the product. A page published with Clione, for example, carries a single `@graph` with [Organization](/glossary/organization-schema/), [WebSite](/glossary/website-schema/), BreadcrumbList and Product, plus [FAQPage](/glossary/faqpage/) when it has questions, and its Product node has a stable `@id` that coexists with the theme's instead of duplicating it.


Thinking that, because the block is not visible, it can say anything. Google asks for the opposite, with a JSON-LD example: if the markup describes an artist, the body of the page has to describe that same artist. What the reader does not see is not marked up.[^google-sd-policies]


## How to check it

1. **Open the page's source code** (not the browser inspector) and search for `application/ld+json`. Count how many blocks there are and which `@type` each declares: that is what your server serves.
2. **Run the same URL through the [Rich Results Test](/glossary/rich-results-test/).** It supports JSON-LD, microdata and RDFa, tells you which types it finds with their errors and suggestions, and also accepts a pasted code snippet.[^rich-results-test]
3. **Compare the two readings.** If the test finds a block that the source code did not have, JavaScript is adding it, and for price and availability that has the cost Google describes.[^google-js-sd]
4. **If there are two product nodes, compare their data.** If they do not say the same thing, at least one does not represent the page.[^google-sd-policies]

## Related concept: microdata

Microdata is the other common way of writing the same vocabulary. It is part of the HTML standard and adds groups of name-value pairs **in parallel to content that already exists**, with attributes such as `itemscope`, `itemtype` and `itemprop` on the visible tags.[^whatwg-microdata] JSON-LD does the opposite: it describes the page in a separate block. Google supports both and recommends JSON-LD.[^google-sd-intro] The practical difference is where the data lives: in microdata it is stuck to the text the customer reads, and in JSON-LD it can be changed without touching the layout, at the risk that it stops matching it.

To go further, the [structured data reading path](/learn/structured-data/) orders the rest of the terms, and the guide to [auditing a product page's structured data](/guides/audit-product-page-structured-data/) applies these steps to a whole page.
