- 7 min read
Shopify Metaobjects: Content Models Without a Second CMS
Every store eventually needs content that is not a product: size guides, care instructions, ingredient tables, shipping rules per country, a list of stockists. The usual answers are a page full of hand-written HTML, or a second CMS wired in with an app. Metaobjects are the third option, and most of the time they are the right one.
Define the shape once
A metaobject definition is a content type: a name, a handle, and typed fields. A size guide might be a rich text field, a list of rows, and an image. Merchants then create entries in the admin, with validation, instead of pasting markup into a page.
Connect entries to products with a metafield of type metaobject_reference, and a
product template can render the right guide with no conditionals:
{%- assign guide = product.metafields.custom.size_guide.value -%}
{%- if guide -%}
<section class="size-guide">
<h2>{{ guide.title }}</h2>
{{ guide.body | metafield_tag }}
{%- if guide.chart != blank -%}
<table>
{%- for row in guide.chart.value -%}
<tr><th>{{ row.label }}</th><td>{{ row.measurement }}</td></tr>
{%- endfor -%}
</table>
{%- endif -%}
</section>
{%- endif -%}
The same content from the Storefront API
On a headless front-end the same entries come back over GraphQL, which means one content model serves both the theme and the custom storefront:
query SizeGuides($first: Int!) {
metaobjects(type: "size_guide", first: $first) {
nodes {
handle
fields {
key
value
reference {
... on MediaImage { image { url altText width height } }
}
}
}
}
}
The fields array is flat key/value pairs, so it is worth normalising it once at
the edge of your data layer rather than reaching into it from components:
const toObject = (node: MetaobjectNode) =>
Object.fromEntries(node.fields.map((f) => [f.key, f.reference ?? f.value]));
A quiet SEO win
Because the content is structured, you can emit structured data from it instead of writing
JSON-LD by hand. A metaobject of type faq becomes a FAQPage block, and
the answers stay in sync with the page because they come from the same source.
Structured content is not only tidier for the merchant. It is the difference between schema that drifts out of date and schema that cannot.
When not to reach for them
- Long editorial content. If the team wants drafts, previews and scheduling, they want a CMS. Metaobjects have none of that.
- Deeply nested models. References work, but a model five levels deep is painful to edit in the admin.
- Content shared across several stores. Entries live in one shop. Duplication starts quickly.
For everything else — structured, store-specific content that merchants should own — they remove an entire integration from the stack. That is usually worth more than the features you give up.