If you’ve ever needed to add stylists, locations, recipes, FAQs, sizing charts, ingredients, or testimonials to a Shopify store and didn’t want to install three apps, metaobjects are what you’ve been looking for. Here’s the version that should have been in the docs.
What metaobjects are
A metaobject is a custom content type. You define it once with a name and fields, then create as many entries as you want, and reference them from anywhere in your store.
Built-ins like products and collections have a fixed schema. Metaobjects are how you create your own schemas without writing a custom app.
When to use them
Use metaobjects when the content:
- Is structured (has the same fields each time)
- Is referenced from multiple places (a stylist appears on three pages)
- Doesn’t fit cleanly into product or collection metafields
Common ones we set up:
- Team / stylists / authors — name, photo, bio, role, social links
- Stores / locations — address, phone, hours, map link, photos
- FAQs — question, answer, category
- Recipes — name, ingredients (linked to products), steps, time
- Testimonials — author, quote, rating, source link
- Press / press features — outlet, headline, link, date
- Sizing charts — region, garment type, measurements grid
- Ingredient libraries — name, description, sourcing, linked products
When NOT to use them
- One-off content. If a piece of data only lives on one page, just use that section’s settings.
- Highly dynamic data. Metaobjects don’t have a real-time API. If your data changes by the second (inventory, pricing), use products or apps.
- Long-form articles. That’s the blog.
- Anything you’d query externally for filtering. Search and filter on metaobjects is limited; use products + tags or metafields for filterable data.
How to set one up cleanly
In Shopify admin:
- Settings → Custom data → Metaobjects → Add definition.
- Name it singular (
Stylist, notStylists). Shopify generates the plural automatically. - Add fields. Use the most specific type each field allows —
emailfor emails,urlfor URLs,single_line_text_fieldfor short strings,rich_text_fieldfor body content. - For relationships, use
mixed_referenceormetaobject_reference— these create proper links rather than orphaned IDs. - Make at least one field “the display name.” Click the gear icon on the field. This is what shows in admin lists and metaobject pickers.
- Save. Now create entries.
Referencing metaobjects from a theme
In your theme’s section schema:
{
"type": "metaobject",
"id": "featured_stylist",
"label": "Featured stylist",
"metaobject_type": "stylist"
}
In Liquid:
{% assign stylist = section.settings.featured_stylist %}
{% if stylist %}
<h3>{{ stylist.name }}</h3>
<img src="{{ stylist.photo | image_url: width: 600 }}" alt="{{ stylist.name }}">
<p>{{ stylist.bio }}</p>
{% endif %}
For a list of metaobjects (e.g. all FAQs):
{% assign faqs = shop.metaobjects.faq.values %}
{% for faq in faqs %}
<details>
<summary>{{ faq.question }}</summary>
<div>{{ faq.answer }}</div>
</details>
{% endfor %}
A subtle gotcha
Metaobjects have entry types but don’t have taxonomy — there’s no native concept of “this metaobject is a child of that metaobject.” If you need hierarchy, you build it via reference fields.
For example, FAQ → Category. Make a FAQ Category metaobject with name. Add a category field on the FAQ metaobject of type metaobject_reference pointing at FAQ Category. Now you can group FAQs.
When the alternative is better
If you find yourself building dozens of fields, or trying to model relationships three layers deep, you’ve probably outgrown metaobjects and should look at:
- A headless setup with Sanity, Contentful, or Shopify’s own Content API
- A purpose-built app (recipes, FAQs, store locators all have decent dedicated apps)
Metaobjects are great until they aren’t. They’re great about 90% of the time.