Back to Blog
Shopify Development

Shopify Metafield Not Showing in Liquid: Fixed

Alex SterlingOctober 9, 20265 min read
Shopify Metafield Not Showing in Liquid: Fixed

You set a metafield in the admin, referenced it in Liquid, and the page renders nothing.

No error, no warning — just an empty space. Liquid fails silently on missing values, which makes this frustrating to debug. There are four causes and a fast way to tell them apart.

Symptom

  • {{ product.metafields.custom.care_instructions }} outputs nothing.
  • The value is clearly populated in Settings → Custom data.
  • It may work in the theme editor preview but not on the live storefront.
  • Or it renders as ProductMetafield / [object Object] instead of the value.

Cause

1. Namespace or key mismatch

The reference must match exactly, including case. A definition in namespace custom with key care_instructions is not reachable as custom.careInstructions or Custom.care_instructions.

2. Storefront access is off

Metafields created via the Admin API, or older definitions, may not be exposed to the storefront. Liquid cannot read them until they are.

3. Wrong output syntax for the type

Since metafields became typed objects, the correct output depends on the type. Printing the object itself gives you the object, not the value.

4. Reading from the wrong owner

Product metafields are not variant metafields. product.metafields will never contain something set on a variant, a collection or the shop.

Fix

Step 1 — dump what actually exists

Before guessing, print everything:

{%- comment -%} Temporary debug block — remove before release. {%- endcomment -%}
<pre style="white-space:pre-wrap">
{%- for field in product.metafields.custom -%}
  {{ field[0] }} = {{ field[1] }} (type: {{ field[1].type }})
{% endfor -%}
</pre>

To sweep every namespace:

{%- for ns in product.metafields -%}
  <strong>{{ ns[0] }}</strong>
  {%- for field in ns[1] -%}
    <div>{{ ns[0] }}.{{ field[0] }} — {{ field[1].type }}</div>
  {%- endfor -%}
{%- endfor -%}

If your field is absent entirely, it is cause 2 or 4. If it is present, it is cause 1 or 3.

Step 2 — enable storefront access

Settings → Custom data → Products → your definition → confirm Storefronts access is enabled. For API-created metafields, set it explicitly:

mutation {
  metafieldDefinitionUpdate(definition: {
    namespace: "custom"
    key: "care_instructions"
    ownerType: PRODUCT
    access: { storefront: PUBLIC_READ }
  }) {
    updatedDefinition { id }
    userErrors { field message }
  }
}

Step 3 — output correctly for the type

{%- comment -%} single_line_text_field / multi_line_text_field {%- endcomment -%}
{{ product.metafields.custom.care_instructions.value }}

{%- comment -%} rich_text_field — metafield_tag renders the HTML {%- endcomment -%}
{{ product.metafields.custom.description | metafield_tag }}

{%- comment -%} file_reference — .value is the file object {%- endcomment -%}
{%- assign guide = product.metafields.custom.size_guide.value -%}
{%- if guide -%}
  <img src="{{ guide | image_url: width: 800 }}" alt="Size guide" width="800" height="600">
{%- endif -%}

{%- comment -%} list.* — .value is an array {%- endcomment -%}
{%- for feature in product.metafields.custom.features.value -%}
  <li>{{ feature }}</li>
{%- endfor -%}

{%- comment -%} product_reference {%- endcomment -%}
{%- assign related = product.metafields.custom.pairs_with.value -%}
{%- if related -%}
  <a href="{{ related.url }}">{{ related.title }}</a>
{%- endif -%}

The rule: .value for almost everything, | metafield_tag for rich text.

Step 4 — guard against missing values

Metafields are frequently unset on some products. Always check before rendering surrounding markup:

{%- assign care = product.metafields.custom.care_instructions.value -%}
{%- if care != blank -%}
  <div class="product-care">
    <h3>Care instructions</h3>
    {{ care }}
  </div>
{%- endif -%}

Without the guard you ship an empty heading on every product that lacks the field.

Verify

  1. Load a product with the metafield set — value renders.
  2. Load one without it — no empty heading, no broken markup.
  3. View source on the live storefront, not just the theme editor preview.
  4. Remove the debug block.

Prevent

  • Define metafields in the admin, not ad hoc via API, so storefront access and type are explicit.
  • Keep a naming convention — lowercase with underscores, one namespace per concern.
  • Always wrap in a != blank check.
  • Document which templates use which metafields, so a definition is never deleted while still referenced.

Frequently asked questions

Why does it work in the theme editor but not live?

Usually an unpublished definition change, or the editor previewing a different product. Always confirm against the live URL.

Can I read another product's metafields?

Yes, via a product_reference metafield or by looking the product up in all_products, but each lookup costs render time. Avoid it inside large loops.

What is the difference between .value and printing the metafield directly?

Printing the metafield gives you the object. .value gives the typed content. Older themes predate typed metafields, which is why tutorials disagree.

Need a hand?

We build Shopify themes that use custom data properly, for merchants in the USA, UAE, Saudi Arabia, Qatar and the UK. If metafields are not behaving, get a free audit or see our Shopify development work.

Share
#Shopify metafield not showing#Shopify metafield Liquid#Shopify metafield storefront access#Shopify metafield namespace#Shopify custom data#Shopify theme debugging
Y

The Yaxify Team

Shopify & Web Development Agency

We build custom Shopify stores and high-performance websites for growing businesses across the USA, UK, and UAE. Everything we publish comes out of client work we have actually shipped.

More about Yaxify →

Ready to start your project?

Get a free consultation and custom quote within 24 hours

No commitment required • Response within 2 hours