Problem Description:
I’m trying to access a metaobject’s fields directly in Liquid, but the fields are returning null, even though the metaobject is properly created and assigned.
Here are the details of my setup:
-
Metafield Configuration:
- Metafield: custom.primary_material
- Type: Single metaobject reference
- References: Metaobject of type material
-
Metaobject Configuration:
- Metaobject Type: material
- Fields in Metaobject:
- material.name (Name of the material)
- material.description (Description of the material)
- Status: The metaobject is set to Active in Shopify Admin.
-
Liquid Code: I’m using the following Liquid code to access the metaobject fields:
{% assign material = shop.metaobjects.material['teak'] %}
<div>
<h3>Debugging Material Metaobject</h3>
{% if material %}
<!-- Debug Metaobject Fields -->
<p><strong>Raw Fields:</strong> {{ material.fields | json }}</p>
<p><strong>Material Name:</strong> {{ material.fields['material.name'] }}</p>
<p><strong>Material Description:</strong> {{ material.fields['material.description'] }}</p>
{% else %}
<p>No material metaobject found.</p>
{% endif %}
</div>
-
Expected Behavior:
- The metaobject with the handle teak exists in the material type.
- I expect to see material.name and material.description fields populated in the rendered output.
-
Actual Behavior:
- The material metaobject is found (Raw Value: MetaobjectDrop), but material.fields returns null.
- As a result, material.fields[‘material.name’] and material.fields[‘material.description’] are empty.
Debugging Attempts:- Verified that the material metaobject type has fields material.name and material.description.
Full Debugging Output:
Here’s the rendered output when I use the debugging code:
Debugging Material Metaobject
Raw Fields: null
Material Name:
Material Description:
Additional Observations:- If I try to list all metaobjects of type material using:
```
{% for material_entry in shop.metaobjects.material.values %}
<p>Handle: {{ material_entry.system.handle }}</p>
{% endfor %}
```
It correctly displays the handle teak, confirming the metaobject exists.
Question:1. Why is material.fields returning null even though the metaobject is set to Active and has fields configured?
- Is there something wrong with how I’m accessing the fields, or could there be an issue with the metaobject setup?
MWE (Minimal Working Example):
Here’s the code I’m using to directly access and debug the metaobject fields:
{% assign material = shop.metaobjects.material['teak'] %}
<div>
<h3>Debugging Material Metaobject</h3>
{% if material %}
<!-- Debug Metaobject Fields -->
<p><strong>Raw Fields:</strong> {{ material.fields | json }}</p>
<p><strong>Material Name:</strong> {{ material.fields['material.name'] }}</p>
<p><strong>Material Description:</strong> {{ material.fields['material.description'] }}</p>
{% else %}
<p>No material metaobject found.</p>
{% endif %}
</div>
I now try to access a specific material but obviously this should be populated dynamically for each product.
Context:- Theme: Custom theme (Next) using Custom Liquid blocks in Product Template.
- Objective: To display material.name (and material.description) for the metaobject teak.
- Extra: I can scale this for other metafields referencing metaobjects.
What I Need Help With:1. Why are the fields returning null?
- Are there additional steps or configurations needed for accessing metaobject fields in Liquid?
Any guidance or suggestions would be greatly appreciated. Thank you! 
How can I create this product specification table?
Hi @Maxplaining
First, Shopify metaobject is object array type so we have to treat it as such.
- Call the metaobject values. This will return an array. I am assuming your metaobject name is material
{% assign materials = shop.metaobjects['material'].values %}
OR
{% assign materials = shop.metaobjects.material.values %}
- Since the material is an array, we have to use iterations e.g. forloop,
{% for material in materials %}
{{ material }}
{% endfor %}
- Depending on what data you have under material e.g. richtext, file, product. You have to treat it differently. I would suggest to console log the values to understand the data
Below is the updated code
{% assign materials = shop.metaobjects.material.values %}
<div>
<h3>Debugging Material Metaobject</h3>
{% for material in materials %}
<!-- Debug Metaobject Fields -->
<p><strong>Raw Fields:</strong> {{ material.fields | json }}</p> <!-- You might have to use forloop on this -->
<p><strong>Material Name:</strong> {{ material.fields['material.name'] }}</p> <!-- I am a little confuse what data do you have -->
<p><strong>Material Description:</strong> {{ material.fields['material.description'] }}</p>
{% endfor %}
</div>
Hi @made4Uo
I got the list of available materials to work, but for the actual items listed from that metaobject in the metafield on the product page it remains blank.
### Materials for This Product
{% assign primary_material = product.metafields.custom.primary_material.value %}
{% if primary_material %}
**Primary Material:** {{ primary_material.name }}
{% else %}
No primary material is selected for this product.
{% endif %}
{% assign secondary_material = product.metafields.custom.secondary_material.value %}
{% if secondary_material %}
**Secondary Material:** {{ secondary_material.name }}
{% else %}
No secondary material is selected for this product.
{% endif %}
{% assign materials = shop.metaobjects.material.values %}
### Material List
{% for material in materials %}
**Material Name:** {{ material.name }}
**Material Description:** {{ material.description }}
{% endfor %}
Below are some screenshots for reference.
Hi @Maxplaining
Thank you for providing your structure. To call the metaobject with your structure, you can just add a value on the end of the product metafield
{% assign material = product.metafields.custom.primary_material.value %}
Hello @made4Uo
This now works for me on the correct product:
{% assign material = product.metafields.custom.primary_material.value %}
{% if material %}
Primary Material: {{ material.name.value }}
{% endif %}
When I try another metaobject (list) with the loop:
{% assign usps = product.metafields.custom.usp.value %}
### Unique Selling Points (USPs)
**Debug - Raw Value:** {{ usps | json }}
{% if usps and usps.size > 0 %}
**Debug - Number of USPs:** {{ usps.size }}
{% for usp in usps %}
**USP Title:** {{ usp.title.value }}
{% endfor %}
{% else %}
No unique selling points available for this product.
{% endif %}
I get this result:
Unique Selling Points (USPs)
Debug - Raw Value: [{"icon":["gid:\/\/shopify\/MediaImage\/46545862558019"],"title":"Teak","url":"https:\/\/cdn.shopify.com\/s\/files\/1\/0790\/2281\/7603\/files\/4so-icon_Teak.png?v=1714041306"},{"icon":["gid:\/\/shopify\/MediaImage\/46545862525251"],"title":"Rope","url":"https:\/\/cdn.shopify.com\/s\/files\/1\/0790\/2281\/7603\/files\/4so-icon_Rope_603ecc5d-7e7d-4f1d-8f24-1027f7eff26c.png?v=1714041306"},{"icon":["gid:\/\/shopify\/MediaImage\/46545862590787"],"title":"5 Year Warranty","url":"https:\/\/cdn.shopify.com\/s\/files\/1\/0790\/2281\/7603\/files\/4so-icon_5_jaar_garantie.png?v=1714041305"}]
No unique selling points available for this product.
How can I now make sure I get those entries in a formatted record so that I could build a specifications table from both metafields with their values and metafields referencing a metaobject (single or list)?
Solved my problem with below code:
{% assign materials = product.metafields.custom.materials.value %}
{% if materials %}
{% else %}
{% endif %}
{% assign primary_material = product.metafields.custom.primary_material.value %}
{% if primary_material %}
{% endif %}
{% assign secondary_material = product.metafields.custom.secondary_material.value %}
{% if secondary_material %}
{% endif %}
{% assign colors = product.metafields.shopify['color-pattern'].value %}
{% if colors %}
{% else %}
{% endif %}
{% assign stackable = product.metafields.custom.stackable.value %}
{% if stackable %}
{% endif %}
{% assign maximum_seats = product.metafields.custom.maximum_seats.value %}
{% if maximum_seats %}
{% endif %}
{% assign shipment_weight = product.metafields.custom.shipment_weight.value %}
{% if shipment_weight %}
{% endif %}
{% assign shape = product.metafields.custom.shape.value %}
{% if shape %}
{% endif %}
{% assign item_quantity = product.metafields.custom.item_quantity.value %}
{% if item_quantity %}
{% endif %}
{% assign fabric_description = product.metafields.custom.fabric_description.value %}
{% if fabric_description %}
{% endif %}
{% assign collection = product.metafields.custom.collection.value %}
{% if collection %}
{% endif %}
| Product Specificaties | |
| - | - |
| Materials | <br>{% for material in materials %}<br>{{ material.name }}{% if forloop.last == false %}, {% endif %}<br>{% endfor %}<br> |
| Materials | No materials available for this product. |
| Primary Material | {{ primary_material.name }} |
| Secondary Material | {{ secondary_material.name }} |
| Colors | <br>{% for color in colors %}<br><br><br><br><br><br><br><br><br>{{ color.label }}{% if forloop.last == false %}, {% endif %}<br><br><br>{% endfor %}<br> |
| Colors | No colors available for this product. |
| Stackable | {{ stackable | capitalize }} |
| Maximum Seats | {{ maximum_seats }} |
| Shipment Weight | {{ shipment_weight }} kg |
| Shape | {{ shape.label }} |
| Item Quantity | {{ item_quantity }} |
| Fabric Description | {{ fabric_description }} |
| Collection | {{ collection }} |