Shopify Nutrition and Allergen Metafields Not Showing: Fixes
Your product page shows the Nutrition heading or empty allergen bullets, but no values. The usual causes, from definitions to Liquid types, and how to fix each.
In this guide
You added nutrition and allergen fields to your products, filled them in, and added a block to the product page. The storefront shows the heading “Nutrition information”, maybe a row of bullet points for allergens, and nothing else. No numbers, no allergen names.
This happens in a handful of predictable ways. The heading comes from the theme, so it always shows. The values come from metafields, and somewhere between the product and the page the connection is missing or reading the wrong thing. This guide walks through the causes in the order worth checking, with a fix for each.
How the pieces fit together
Four things have to line up for a metafield value to reach a product page:
| Piece | Where you find it | What goes wrong |
|---|---|---|
| Metafield definition | Settings > Custom data > Products | Missing, or a different namespace, key or type than you think |
| Value on the product | The Metafields section of the product page in admin | Empty for this product, or set on the variant instead |
| Theme block or section | Theme editor, product template | Static text instead of a connected source, or a different template |
| Liquid code | The theme’s section or snippet file | Wrong path, missing .value, or code written for another type |
Shopify’s help center describes metafield definitions as templates that specify what part of your store a metafield applies to and what values it can have. A definition has a namespace and key, such as custom.allergens, and a type, such as single line text, a list of single line text, JSON or rich text.
Step 1: Confirm the product actually has a value
Start with the boring check, because it is the most common one.
- Open the product in the Shopify admin.
- Scroll to Metafields and look at the nutrition and allergen fields.
- If a product has variants and your fields are variant metafields, open a variant and check there too.
If the field is empty on this product, the theme has nothing to show. Many theme blocks still render their heading, so an empty value looks like a broken block. Test on a product you know is filled in before changing any code.
If you filled in hundreds of products by CSV or an app, open two or three at random. A column that did not match during import leaves the field empty without an error. Our guide to the Shopify product CSV covers how imports map columns.
Step 2: Check the namespace, key and type
Go to Settings > Custom data > Products and open each definition. Write down three things:
- Namespace and key, for example
custom.allergens. Note singular or plural, underscores and spelling. - Type, for example “List of single line text” or “JSON”.
- Whether the definition is the one your products actually use. It is easy to end up with
custom.allergenandcustom.allergensafter an import or a theme change.
Metafields that were created without a definition, for example by an older import or an app, are listed separately in that area as metafields without a definition. You can add a definition to them to give them a name and a type. If a metafield you expect is not offered in the theme editor, a missing definition or an unsupported type is the first thing to check.
Step 3: Check the product template and the block
Open the theme editor on the product that should show values.
- Check the template. At the top of the editor, make sure you are editing the template this product uses. If the product is assigned an alternate template, such as
product.food, the block you configured on the default template is not on its page. - Check the block content. Click the block that shows the heading. In many themes, a collapsible row or text block has a heading field and a content field. The heading is plain text. The content has to be connected to the metafield with the Connect dynamic source icon next to the field.
- Check what is connected. If the content shows a source, hover or click it to see which metafield it points to. A block connected to
custom.nutrition_tablewhile your values live incustom.nutritionshows an empty panel.
Shopify’s help page on displaying metafields on your online store explains the connect step and notes that a list of content types can be connected to Text or Rich text blocks.
Type compatibility in the theme editor
A theme setting can only connect to metafield types it supports. Shopify’s developer docs on dynamic sources list the compatible types for each setting. In short:
- A Text or Rich text setting accepts text, number, date, measurement and similar types, plus lists of them.
- An image setting accepts a file reference.
- A JSON metafield is not one of the types you can connect to a text setting.
If your nutrition data is a JSON metafield, a standard text block cannot show it. You need a custom section, a custom Liquid block or an app block that reads the JSON in code.
Step 4: Debug the Liquid
If your theme or a developer reads the metafields in code, add a temporary line to the section to see exactly what Liquid receives:
{%- assign mf = product.metafields.custom.allergens -%}
<pre>type: {{ mf.type }} | list: {{ mf.list? }} | value: {{ mf.value | json }}</pre>
Load the product page and read the output:
- Nothing after
type:means Liquid did not find a metafield at that namespace and key on this product. Go back to Step 1 and Step 2. - A type you did not expect, such as
list.single_line_text_fieldwhen the code expects plain text, means the code and the definition disagree. - A value that looks right means the problem is in how the template prints it.
Remove the debug line when you are done, because it is visible to customers.
Access the value, then the field
Shopify’s metafield object reference shows the access path as resource.metafields.namespace.key, with a value property that holds the data. For list types, value returns an array. For JSON, value returns an object whose properties you read by name.
A typical bug in a nutrition table reads a key that is not in the JSON:
{%- assign nutrition = product.metafields.custom.nutrition.value -%}
<td>{{ nutrition.energy }}</td>
If the stored JSON is {"energy_kj": 1550, "energy_kcal": 370, "fat": 12.5}, there is no energy property, so the cell is empty while the row label still shows. Match the property names exactly:
<td>{{ nutrition.energy_kj }} kJ / {{ nutrition.energy_kcal }} kcal</td>
Empty bullets: the list is there, the field name is not
Empty allergen bullets usually mean the loop runs, so the list has items, but each item prints nothing. With a list of metaobjects, the code has to name a field that exists on the metaobject definition:
<ul>
{%- for allergen in product.metafields.custom.allergens.value -%}
<li>{{ allergen.name.value }}</li>
{%- endfor -%}
</ul>
If the allergen metaobject’s field key is label, not name, you get one empty <li> per allergen. Use the field key from the metaobject definition, here allergen.label.value.
With a list of single line text, each item is already the text, so print the item itself:
{%- for allergen in product.metafields.custom.allergens.value -%}
<li>{{ allergen }}</li>
{%- endfor -%}
List versus single value
Code written for one type breaks on the other:
| Definition type | What the code must do |
|---|---|
| Single line text | Print the value directly |
| List of single line text | Loop over .value, or use the metafield_tag filter |
| JSON | Read named properties from .value |
| Rich text | Pass the metafield to the metafield_tag filter, which outputs HTML |
| List of metaobject references | Loop over .value and print a field of each entry |
The metafield_tag filter generates HTML for many types, including a list element for a list of single line text. Shopify notes that it does not support list types other than single line text and metaobject reference lists.
If you changed a definition from single text to a list after products were filled in, also check that the old values were converted. The safest route is to export a few products, check the field, and re-enter values where needed.
Pitfalls we see often
- Testing on the wrong product. A preview product without values looks exactly like a broken block.
- Two definitions with similar keys.
custom.allergensfrom a theme tutorial andcustom.allergen_listfrom an import. Pick one, move the data, delete the other. - Values on variants, code on products.
product.metafieldsdoes not read variant metafields. Useproduct.selected_or_first_available_variant.metafieldsif the data lives on variants. - Square brackets for some keys. The metafield reference notes that keys named
size,firstorlastneed square bracket notation, such asproduct.metafields.custom['size']. - The Storefronts access option. Shopify’s help describes this option as letting custom storefronts display a metafield’s values. It is not the switch to try first for an empty block on an Online Store theme.
- Hiding empty blocks. Wrap your block in
{% if product.metafields.custom.nutrition.value != blank %}so products without data do not show an empty heading.
When a developer or an app is the better fix
If you sell food into the EU, these fields are not decoration. The nutrition declaration and allergen information have to be correct and visible before purchase, as we explain in our guide to EU allergen and food information for online shops. A setup that depends on hand-written Liquid across several templates is fragile, and each theme update is a chance to lose it.
You have three ways forward:
- Fix the current setup with the steps above, then document the namespace, key and type of each field so the next person does not create a duplicate.
- Have a developer build a single section that reads all food fields and hides itself when they are empty. Our guide on how to brief a developer for a custom Shopify app helps you describe the job clearly, and when to build a custom Shopify app helps you decide whether a custom build is worth it.
- Use an app with its own theme block, where the app owns both the data format and the block that reads it, so the two cannot drift apart.
We built EU Food Labels for the third option. It stores each label in one JSON product metafield and shows it through a theme app block that renders nothing on products without a label. The app is not on the Shopify App Store yet.
FAQ
Why does my metafield show in the admin but not on the product page?
The value exists, but the page is not reading it. Check that the product uses the template you edited, that the block’s content is connected to the right metafield, and that any Liquid uses the same namespace, key and type as the definition.
Why can’t I connect my nutrition metafield in the theme editor?
The setting probably does not accept that metafield type. A JSON metafield cannot be connected to a text block, for example. Use a type the setting accepts, or read the metafield in a custom section or app block.
Why do my allergen bullets show but stay empty?
The loop finds items but prints a field that does not exist. For a list of metaobjects, use the exact field key from the metaobject definition. For a list of text, print the item itself.
Do I need to enable Storefronts access for theme metafields?
Shopify describes that option as making values available to custom storefronts. For an empty block on an Online Store theme, check the value, definition, template and Liquid first.