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

# Metafields

> Preload Shopify metafields onto products and variants so you can read them from transforms, intents, and views.

Declare additional Shopify metafields you want Swish to fetch alongside product and variant data. Once preloaded, metafield values are available on `product.metafields` and `variant.metafields` (keyed by namespace, then by key) and are passed to [transforms](https://swish.app/docs/guides/customize/transforms.md), [intents](https://swish.app/docs/guides/customize/intents.md), and view sections.

```js theme={null}
window.SwishOptions = {
  metafields: {
    product: ["custom.material", "custom.care_instructions"],
    productVariant: ["custom.weight"],
  },
};
```

Each entry is a `namespace.key` string. Metafields are loaded with the rest of the product data, so they are available the moment the product is rendered.

| Option | Type | Default | Description |
| - | - | - | - |
| `product` | `string[]` | `[]` | Product metafields to fetch. |
| `productVariant` | `string[]` | `[]` | Variant metafields to fetch. |

## Reading a metafield value

Metafields are exposed as a nested record keyed by namespace, then by key. Any namespace you declared in `metafields.product` or `metafields.productVariant` is always present (as `{}` when no values are set), so you only need optional chaining at the namespace level for namespaces you didn't declare.

```js theme={null}
const value = product.metafields.custom?.material;
```

For namespaces that contain special characters (for example, app-reserved namespaces like `$app:swish`), use bracket access:

```js theme={null}
const value = product.metafields["$app:swish"]?.setup;
```

Values are always strings. Cast or parse them as needed for non-string types (numbers, JSON, references).

## Using metafields in transforms

Metafields pair naturally with [transforms](https://swish.app/docs/guides/customize/transforms.md) when you want to override how a product is displayed based on data in your Shopify admin.

```js theme={null}
window.SwishOptions = {
  metafields: {
    product: ["swish.price_label"],
  },
  transforms: {
    productPrice: ({ product }) => product?.metafields.swish?.price_label,
  },
};
```

## Using metafields in intents

You can also read metafields from intent callbacks like `saveProduct.promptVariantIfMissing`:

```js theme={null}
window.SwishOptions = {
  metafields: {
    product: ["custom.skip_variant_select"],
  },
  intents: {
    saveProduct: {
      promptVariantIfMissing: ({ product }) =>
        product.metafields.custom?.skip_variant_select !== "true",
    },
  },
};
```

> [!WARNING]
>
> Only declare the metafields you actually use. Each entry adds a field to the
> Shopify Storefront API query, which counts against your storefront cost
> budget.

## Further reading

* [Transforms](https://swish.app/docs/guides/customize/transforms.md) for customizing how product data is rendered
* [Intents](https://swish.app/docs/guides/customize/intents.md) for behavior callbacks that can read metafields
* [Configuration reference](https://swish.app/docs/references/sdk/configuration.md) for all SDK options


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.