# Shopify metafields to feed attributes

Metafields are where the values a feed needs but Shopify has no field for actually live: gender, age group, material, net quantity, energy labels, style codes. They are also typed, namespaced and inconsistently populated, so reading one is more involved than reading a product field.

- **Canonical URL:** https://www.feedlab.io/knowledge/mappings/shopify-metafields-to-feed-attributes
- **Last reviewed:** 18 September 2026
- **Source:** feedlab knowledge base
- **Licence:** free to quote and cite with attribution to feedlab


## The Shopify side

| Property | Value |
| --- | --- |
| API field | `product.metafields / variant.metafields` |
| Called | Metafields |
| Found at | Product → Metafields at the bottom of the product page, and Settings → Custom data for the definitions |


## Before and after

| In Shopify | In the feed | Note |
| --- | --- | --- |
| `custom.material = "100% merino wool"` | `material Wool` | Free text normalised to a filterable value. |
| `custom.gender = "Mens"` | `gender male` | Merchant wording mapped to the channel's enumerated value. |
| `custom.net_volume = {value: 250, unit: ml}` | `unit_pricing_measure 250ml` | A dimension metafield carries value and unit separately and has to be composed. |
| `custom.style_code = "OXF-100"` | `item_group_id OXF-100` | Grouping across products that model colour separately. |
| `custom.care = ["Machine wash", "Do not bleach"]` | `Machine wash. Do not bleach.` | A list metafield joined for a single-value field. |
| `custom.material not set` | `(fallback or omitted)` | Partial coverage is normal, so every metafield mapping needs a fallback. |



## The transformation, step by step

1. **Address the metafield by namespace and key** — Every metafield is identified by a namespace and a key together, such as custom.material. The key alone is ambiguous, because two apps can define the same key in different namespaces, and they do.
2. **Know the type before you read the value** — A metafield can be a string, an integer, a dimension, a rating, a JSON object, a list, or a reference to another resource. A dimension is stored as a value and a unit together, a reference returns an ID that has to be resolved, and a list returns several values where the feed wants one.
3. **Decide between product and variant level** — Material usually belongs to the product, net quantity to the variant. Reading a product metafield for a value that genuinely varies per variant sends the same answer on every row, which is worse than sending nothing because it is confidently wrong.
4. **Handle the definition being unpopulated** — A metafield definition existing does not mean every product has a value. Coverage in a real catalogue is usually partial, so each mapping needs a fallback and a way to see how many products fell through to it.
5. **Map the value into the channel's vocabulary** — A metafield holds whatever the merchant typed. If it says "Mens" and the channel wants "male", that is still a mapping rather than a passthrough, and the same applies to units, dates and booleans.



## What goes wrong

### A JSON metafield is not a string

Reading a JSON or list metafield as text sends the raw serialised value, so a feed field ends up containing brackets and quotes. It validates, because it is a string as far as the channel is concerned, and it is visible to shoppers.

### Reference metafields return IDs

A metaobject or file reference gives you an ID, not the thing itself. Without resolving it, the feed carries an internal Shopify identifier where a material or an image URL should be, which is a value nobody will recognise as wrong until a shopper sees it.

### App-created metafields are private or namespaced oddly

Metafields written by apps live in their own namespaces and can be app-owned, which affects whether you can read them at all. A value visible in the admin is not automatically a value your feed can access.

### Partial coverage looks like a working mapping

Mapping a metafield that is populated on the twenty products someone checked, and empty on the other four thousand, produces a feed that is correct in the sample and mostly empty in practice. Coverage has to be measured, not assumed.




## How feedlab maps it

feedlab reads metafields by namespace and key with their type respected, so a dimension composes value and unit, a list joins and a reference resolves. Each mapping declares its fallback, and the preview reports coverage per metafield so a mapping that works on twenty products and nothing else is visible before publishing.






## Frequently asked questions

### Can I use Shopify metafields in a product feed?

Yes, and for several attributes they are the only real source. Gender, age group, material, net quantity and style codes have no native Shopify field, so a metafield is where they live.

### Why does my feed show brackets and quotes in a field?

A JSON or list metafield was read as plain text, so its serialised form was submitted. Those types have to be parsed and composed into the single value the attribute expects.

### Should a metafield be on the product or the variant?

Whichever level the value actually varies at. Material is usually per product, net quantity per variant. Reading a product metafield for a per-variant value repeats the same answer on every row.

### How do I know if a metafield is populated across the catalogue?

Measure it before relying on it. Definitions are created far more often than they are filled, and a mapping that works on a handful of products and silently falls through everywhere else is the usual outcome.




## Primary sources

- [Shopify: Metafields](https://shopify.dev/docs/apps/build/custom-data/metafields)
- [Google: Product data specification](https://support.google.com/merchants/answer/7052112)



