> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uselayers.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Metaobjects & Reference Metafields

> How Layers resolves metaobject references, media references, taxonomy values, and nested reference chains into a normalized shape.

Layers fully supports Shopify metaobjects, allowing you to leverage custom data structures defined in your Shopify admin. When a product metafield references a metaobject, Layers automatically resolves the complete metaobject data from a local cache. This gives you access to all fields defined on the metaobject, including nested metaobject references up to 5 levels deep.

All reference-type metafields are normalized into a consistent, predictable structure. This means you always receive the same shape of data regardless of how Shopify returns the raw reference, making it easier to build reliable storefront experiences.

## Supported reference types

The schema supports the following reference types with full data normalization:

| Reference Type              | Description                                           |
| :-------------------------- | :---------------------------------------------------- |
| `metaobject_reference`      | Single reference to a custom metaobject               |
| `list.metaobject_reference` | List of references to custom metaobjects              |
| `file_reference`            | Reference to a file asset (image, video, or document) |
| `product_reference`         | Single reference to another product                   |
| `list.product_reference`    | List of references to other products                  |
| `variant_reference`         | Single reference to a product variant                 |
| `collection_reference`      | Single reference to a collection                      |
| `page_reference`            | Single reference to a Shopify page                    |

## Normalized reference shapes

Each reference type is normalized into a small, consistent object. Transport-only fields like `__typename` are always removed. The shape you receive depends on the type of referenced resource.

**Metaobject references** are resolved into a structure with the metaobject's core identifiers and a key-value map of its fields:

| Field          | Type           | Description                          |
| :------------- | :------------- | :----------------------------------- |
| `id`           | String         | The Shopify GID of the metaobject    |
| `type`         | String         | The metaobject definition type       |
| `handle`       | String         | The metaobject handle                |
| `display_name` | String or null | The display name of the metaobject   |
| `fields`       | Object         | Key-value map of resolved field data |

**Media image references** (including `file_reference` metafields that point to images) are normalized to:

| Field | Type           | Description                        |
| :---- | :------------- | :--------------------------------- |
| `id`  | String         | The Shopify GID of the media image |
| `url` | String         | The CDN URL of the image           |
| `alt` | String or null | The alt text for the image         |

**Taxonomy value references** are normalized to:

| Field  | Type   | Description                            |
| :----- | :----- | :------------------------------------- |
| `id`   | String | The Shopify GID of the taxonomy value  |
| `name` | String | The display name of the taxonomy value |

**Video references** are normalized to:

| Field | Type   | Description                       |
| :---- | :----- | :-------------------------------- |
| `id`  | String | The Shopify GID of the video      |
| `url` | String | The URL of the first video source |

## Nested metaobject resolution

When a metaobject field references another metaobject (via `metaobject_reference` or `list.metaobject_reference`), Layers automatically resolves the nested reference from its local cache. This happens recursively up to 5 levels deep, with circular reference protection to prevent infinite loops.

This is useful for data models where metaobjects reference other metaobjects. For example, a "Product Spec" metaobject that references a "Material" metaobject, which in turn references a "Certification" metaobject.

Non-reference fields are returned as their plain values (strings, numbers, etc.). If a referenced metaobject is not found in the cache, the reference data from Shopify is still normalized into the standard shape.

## Example: metaobject reference response

```json theme={null}
{
  "metafields": {
    "custom": {
      "color_swatch": {
        "id": "gid://shopify/Metaobject/123456",
        "type": "color_swatch",
        "handle": "midnight-blue",
        "display_name": "Midnight Blue",
        "fields": {
          "color": "#191970",
          "name": "Midnight Blue",
          "hex_code": "#191970"
        }
      }
    }
  }
}
```

## Example: list metaobject reference response

```json theme={null}
{
  "metafields": {
    "custom": {
      "available_colors": [
        {
          "id": "gid://shopify/Metaobject/111",
          "type": "color_swatch",
          "handle": "red-swatch",
          "display_name": "Red",
          "fields": {
            "color": "#FF0000",
            "name": "Red"
          }
        },
        {
          "id": "gid://shopify/Metaobject/222",
          "type": "color_swatch",
          "handle": "blue-swatch",
          "display_name": "Blue",
          "fields": {
            "color": "#0000FF",
            "name": "Blue"
          }
        }
      ]
    }
  }
}
```

## Example: media image reference response

```json theme={null}
{
  "metafields": {
    "custom": {
      "hero_image": {
        "id": "gid://shopify/MediaImage/123456",
        "url": "https://cdn.shopify.com/s/files/hero-image.jpg",
        "alt": "Product hero image"
      }
    }
  }
}
```

## Example: nested metaobject reference response

In this example, a product has a "material" metafield that references a Material metaobject, which itself has a "certification" field referencing a Certification metaobject:

```json theme={null}
{
  "metafields": {
    "custom": {
      "material": {
        "id": "gid://shopify/Metaobject/500",
        "type": "material",
        "handle": "organic-cotton",
        "display_name": "Organic Cotton",
        "fields": {
          "name": "Organic Cotton",
          "weight": "150gsm",
          "certification": {
            "id": "gid://shopify/Metaobject/600",
            "type": "certification",
            "handle": "gots-certified",
            "display_name": "GOTS Certified",
            "fields": {
              "name": "Global Organic Textile Standard",
              "level": "Grade A",
              "url": "https://example.com/gots"
            }
          }
        }
      }
    }
  }
}
```

<Note>
  Metaobject data is resolved from a local cache that is kept in sync with Shopify via webhooks. If a referenced metaobject is not found in the cache, Layers normalizes the original reference data from Shopify's GraphQL response into the standard shape, or falls back to the numeric ID if no reference data is available.
</Note>

## See also

* [Metafields](/developers/product-schema/metafields)
* [Metaobjects & Metafields cache and access](/shopify-integration/metaobjects-metafields/cache-and-access)
* [Available attributes for API requests](/developers/product-schema/api-attributes)
