# @graph in JSON-LD: What It Is and How It Organizes Schema

> What @graph is in JSON-LD, what the W3C specification says, how it links a product page's product, store and site, and how to review your store's.

URL: https://clione.ai/glossary/graph/
Lang: en

If you open the [JSON-LD](/glossary/json-ld/) block of a [product page](/glossary/product-page/) and right after `@context` you see `"@graph": [`, what follows is not a node but a list of them: the store, the site, the [breadcrumbs](/glossary/breadcrumbs/) and the product, one after another. `@graph` is not a [Schema.org](/glossary/schema-org/) type like [Product](/glossary/product-schema/) or [Offer](/glossary/offer-schema/), and it has nothing to do with Google's [Knowledge Graph](/glossary/knowledge-graph/): **it is a keyword of the format itself**, in the family of `@context`, `@type` and `@id`. It matters because it decides how your page's [structured data](/glossary/structured-data/) is arranged, and because it is easy to believe it arranges more than it does.

## How it works

The W3C's JSON-LD 1.1 specification gives it two uses. The one you will see in a store is the first: when a document's top level is an object that carries no keys other than `@graph` and, at most, `@context`, **`@graph` expresses the default graph**, the one that would otherwise stay implicit. The specification explains what it is for: when there are several nodes at the top level that share the same context, `@graph` gathers them in a list and lets you declare that context only once.[^w3c-json-ld11]

The alternative is a list of loose nodes, each with its own `@context`. The specification puts the two examples side by side and treats them as equivalent: without `@graph`, the context is repeated on every node.[^w3c-json-ld11] So the first advantage of `@graph` is one of order and weight, not of meaning.

The second use is rare in ecommerce. If the same object that carries `@graph` also carries an `@id`, that identifier is the name of a named graph, and you can make statements about the graph itself, such as the date it was generated.[^w3c-json-ld11] A product page does not need it.

What joins the nodes is something else. The specification distinguishes two ways of relating them: **[embedding](/glossary/embeddings/)** a node inside a property of another, which creates a parent-child relationship, or **referencing** it by its identifier.[^w3c-json-ld11] A reference is an object that carries only `@id` and points to a node described elsewhere in the document.[^w3c-json-ld11] Inside a `@graph` the nodes are siblings, so they connect the second way: the product's offer says it is sold by `{"@id": ".../#organization"}`, and that `@id` is the one on the store's node a few lines above. If it does not say so, the specification is clear: a top-level object with `@graph` is used to define nodes **that may not form a connected graph**.[^w3c-json-ld11]

Nor does it matter much whether everything goes in one block or several. When the JSON-LD content of an HTML page is extracted as RDF, **all the `<script type="application/ld+json">` elements are processed and merged into a single dataset**.[^w3c-json-ld11] A `@graph` with four nodes and four blocks with one node each say the same thing if the identifiers match.

Google does not ask for `@graph`. Its general guidelines say that the more elements you mark up, the more complete a picture it has of the page and the more Search features it can show it in, including [rich results](/glossary/rich-results/). And they say Search understands multiple elements on a page whether you nest them, with a main element and the others grouped under it, or specify them separately. In the second case it asks you to link them: if two elements are better understood together, use `@id` on both; if you do not link them, **Google may not know they go together**.[^google-sd-policies]

## In a store

**Fictional example.** A shirt's product page in an invented store, with the four nodes in a single `@graph`, cut down to the essentials:

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://www.example.com/#organization",
      "name": "Calella",
      "url": "https://www.example.com/"
    },
    {
      "@type": "WebSite",
      "@id": "https://www.example.com/#website",
      "url": "https://www.example.com/",
      "publisher": { "@id": "https://www.example.com/#organization" }
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Shirts",
          "item": "https://www.example.com/shirts"
        },
        { "@type": "ListItem", "position": 2, "name": "Calella linen shirt, blue" }
      ]
    },
    {
      "@type": "Product",
      "@id": "https://www.example.com/calella-linen-shirt#product",
      "name": "Calella linen shirt, blue",
      "offers": {
        "@type": "Offer",
        "price": "39.90",
        "priceCurrency": "USD",
        "seller": { "@id": "https://www.example.com/#organization" }
      }
    }
  ]
}
```

It reads like this. The `@context` goes once, at the top, and applies to all four nodes. The organization has an `@id`, and two nodes cite it by it without describing it again: the website as publisher and the offer as seller. The offer, by contrast, is nested inside the product, because it only makes sense inside it. The two techniques coexist in the same block. Clione does the same: a page published with Clione carries a single `@graph` with [Organization](/glossary/organization-schema/), [WebSite](/glossary/website-schema/), BreadcrumbList and [Product](/glossary/product-schema/), plus [FAQPage](/glossary/faqpage/) when it has questions, and its Product node has a stable `@id` that coexists with the theme's own instead of duplicating it.


Believing that putting two nodes in the same `@graph` already says they are related. It does not: the specification presents the top-level `@graph` precisely as the way to declare nodes that may not be connected, and what connects them is a property that points to the other's `@id`.[^w3c-json-ld11] A product and an organization in the same block, with no `seller` or other reference, are two islands.


## How to check it

1. **Open a product page's source code and search for `application/ld+json`.** Count the blocks and see whether any starts with `@graph`. Several blocks are not an error: the specification treats them as a single dataset.[^w3c-json-ld11]
2. **Note each node's `@id`.** A node without `@id` is valid, but it is anonymous: the specification calls it a blank node, and from outside the document it cannot be cited.[^w3c-json-ld11]
3. **Follow every reference.** Every property that carries only `@id`, like the offer's seller, has to point to a node that exists on the page with that same identifier, letter for letter.[^w3c-json-ld11]
4. **Check that what is better understood together is linked**, like the product and the store that sells it. If it is not, Google may not relate them.[^google-sd-policies]
5. **Run the URL through the [Rich Results Test](/glossary/rich-results-test/)** and compare the elements it detects with the nodes you counted.

## Related concept: the @id identifier

`@graph` and `@id` almost always go together and do different jobs. **`@graph` is the list: it says which nodes exist. `@id` is the name: it says who each one is and lets another cite it.** A block can have `@graph` without a single `@id`, and then it is a list of unrelated nodes; and it can have `@id` without `@graph`, with the nodes nested inside one another. The [`@id` identifier](/glossary/id-json-ld/) has its own entry, which explains how to choose it so it does not change.

To go further, the [structured data reading path](/learn/structured-data/) orders the rest of the terms, and the [product graph](/glossary/product-graph/) draws which nodes surround a product and how they cite each other.
