Most Shopify catalogs have a data problem long before anyone calls it that. A size chart lives as an image pasted into the description. Ingredient lists are typed inline, differently, on every product. A comparison table that should filter and sort is instead three paragraphs of prose nobody reads past the first line. This isn't a content problem — it's a data-modeling problem, and Shopify has had a real answer to it for years: metafields and metaobjects. Most merchants have heard the terms, fewer have used them properly, and almost none have a clear sense of where "type it into the admin" ends and "this needs a developer" begins. This is the honest version of that map.
Why the description field runs out of road
The Shopify product object ships with a fixed set of fields — title, description, price, weight, a handful of options, a body of rich text. That's enough for a simple catalog. It stops being enough the moment a brand needs to say the same kind of thing about every product in a structured, comparable way: fabric composition on every apparel item, allergen data on every food SKU, battery life and charge time on every electronics listing, fit notes on every shoe.
Stuff all of that into the description field and you get three specific failures. First, it doesn't filter or search — a customer looking for "machine washable" or "under 500mAh" has no way to query a paragraph. Second, it doesn't render consistently — one product's ingredient list is a comma-separated sentence, another's is a bulleted mess, because there was never a schema forcing consistency, just whoever wrote that particular description that day. Third, it doesn't stay structured through syncs, exports, or a headless rebuild — a description field is one big string; there's no way to pull "just the care instructions" out of it programmatically without fragile text parsing.
Metafields and metaobjects exist specifically to fix this. They give a catalog actual schema — named fields with defined types, validated on entry, queryable through the API, and reusable across every product that needs them. The difference between a catalog that can support real filtering, structured comparison tables, and a headless frontend, and one that can't, usually comes down to whether this layer was set up properly.
What a metafield actually is
A metafield is a single piece of custom data attached to a standard Shopify resource — a product, a variant, a collection, a customer, an order, a page, even the shop itself. Every metafield has a namespace (a grouping that avoids naming collisions, especially important once apps start adding their own metafields alongside yours), a key (the field's specific name), and a value of a defined type. In Liquid or the API, a metafield reads as product.metafields.namespace.key — namespace and key together are how Shopify finds the right value.
The type system is the part worth understanding properly, because it's more capable than most merchants assume. Beyond plain single-line and multi-line text, there's rich text (for formatted content with bold, links, and lists), number fields split into integer and decimal, boolean, date and date-time, URL, and a genuine set of measurement types — dimension, weight, volume — that store a value with a unit rather than a bare number, so 250 grams stays 250 grams rather than an ambiguous "250" a theme has to guess at. There's also a dedicated money type, a rating type, and a color type for hex values.
The more structurally useful category is reference types: a metafield can point directly at another Shopify object — a product, a variant, a collection, a page, a file, a customer, or a metaobject entry — rather than storing a copy of that data. And most types have a list variant, so a single metafield can hold an array of values (a list of related products, a list of certifications, a list of file references) instead of just one. A metafield definition — the schema a merchant sets up once in the admin — can currently hold up to 256 metafield definitions per resource type for merchant-created fields, with values capped around 64KB for most types (2KB for URL and ID fields, 128KB for JSON), and list types topping out at 128 items, or 256 for lists of metaobject references. Those aren't limits a typical product catalog gets anywhere near, but they matter if you're planning something like a very long structured spec sheet.
What a metaobject actually is, and why it's different
A metaobject is not a field bolted onto an existing resource — it's an entirely custom content type with its own schema, existing independently of any product, variant, or collection. Where a metafield answers "what's one more fact about this product," a metaobject answers "what's a whole new kind of thing my store needs to model." A size-and-fit guide is the clean example: it isn't one fact about one product, it's a structured record — brand, fit philosophy, measurement table, model height and size worn, care notes — that gets created once and then referenced from every product in that fit category. Change the guide once, and every product referencing it updates.
Other things that fit the metaobject shape naturally: an ingredient or nutritional-info block referenced across a whole product line, a brand or collection story content block, an author or reviewer profile referenced from a set of blog posts, a store-locator entry, a warranty terms record, a comparison-table row definition that multiple products plug into. Anything that's genuinely its own entity with its own fields — not just an extra attribute of a product — is a metaobject, not a metafield.
Metaobjects are built from a definition (the schema — what fields it has, and what type each one is, using the same type system as metafields, including references to other metaobjects) and then populated with individual entries against that definition. A merchant-created metaobject definition currently supports up to 128 definitions per shop on Basic, Shopify, and Advanced plans, and 256 on Plus and Enterprise, with each definition allowed up to 40 fields and up to a million entries — Shopify raised that entry ceiling substantially from the older per-plan caps of 64,000 and 128,000. In practice almost no merchant catalog pressures these limits; they matter mainly if you're modeling something at real content-library scale, like a large recipe database or a big multi-brand size-guide library.
How this actually shows up on a product page
This is the part that trips people up, because the honest answer depends heavily on which theme you're running. On a standard Online Store 2.0 theme — which covers the vast majority of Shopify stores today, including Dawn and most paid themes — metafields are not automatically rendered anywhere. Creating a metafield definition and filling in a value for every product does not put that data on the storefront by itself. Someone has to explicitly reference it in a Liquid template, using syntax like {{ product.metafields.namespace.key.value }}, or connect it through the theme editor's dynamic sources feature, which lets a merchant click a text or image block, pick the dynamic-source icon, and wire it to an existing metafield definition without touching code.
Dynamic sources cover a meaningful chunk of simple cases — a single text field, a single image, a simple number — display them within an existing section without any Liquid work. What dynamic sources don't do well is anything structural: a size-chart table with multiple rows and columns pulled from a metaobject list, a comparison grid assembled from several referenced metaobjects, conditional layout based on a field's value, or a metafield rendered differently depending on product type. That's genuine template work — a Liquid section or block built specifically to loop through a metaobject's fields, or a metafield list, and lay it out correctly with the right conditional logic and responsive styling.
Shopify's newer Horizon-family themes push this further, with more first-class metafield and metaobject support baked into blocks and sections out of the box, and better handling of metaobject lists in the theme editor directly. That narrows the gap for common cases, but it doesn't erase the underlying rule: any bespoke layout, any non-trivial structured display, any place where design intent gets specific, still needs a developer writing Liquid against the metafield or metaobject data rather than a merchant clicking dynamic-source connections in the editor.
What a merchant can genuinely do without a developer
Setting up a metafield definition is real self-serve territory. In Settings, then Custom Data, a merchant can create a new definition, name it, choose its type, and decide which resource it attaches to — no code required. Shopify also ships a library of standard metafield definitions for common cases like care instructions, ingredient lists, or product ratings — typing a keyword like "care" into the definition name field surfaces the matching standard definition, with namespace, key, and type pre-filled correctly. Using standard definitions where one exists is worth doing even beyond the convenience, because apps and themes are more likely to already recognize and support them out of the box.
Filling in values is equally self-serve — a merchant can go product by product and populate a metafield, or use the bulk editor to fill it in across many products at once, which is realistic for a few hundred SKUs. Basic metaobject entries work the same way once a definition exists: creating individual entries through the admin's custom data section is a form-filling exercise, not a technical one.
Where self-serve ends is rendering. A merchant can create the perfect data model — every field typed correctly, every product populated, every metaobject entry filled in — and it will not appear on the storefront unless a theme already has dynamic-source support for exactly that layout, or someone builds the Liquid to display it. That gap is the single most common reason a metafield project stalls: the admin work gets done, the storefront never catches up, and three months later a merchant is asking why the size guide they carefully populated still isn't visible to a single customer.
Worked example: a real size and fit guide
Take an apparel brand trying to solve fit uncertainty — probably the single highest-leverage use of this system for a fashion catalog, since fit-related returns are usually the most expensive and most preventable category. The right model is a metaobject definition called something like fit_guide, with fields for a measurement table (structured, not a pasted image), model height and the size they're wearing in product photos, a fit philosophy note (runs small, true to size, oversized by design), and fabric stretch behavior. One entry gets created per fit category — not per product — so a brand with twelve dresses that all cut the same way needs one fit_guide entry, referenced from all twelve products through a metafield of type "metaobject reference" on each product.
On the template side, this needs a dedicated Liquid section that checks whether the product has a fit-guide reference, pulls the referenced metaobject, and renders its fields into a proper table or expandable panel — with fallback behavior for products that don't have one set. That's genuine development work, but it's scoped and bounded: build it once, and every product that gets a fit-guide reference in the future inherits the same rendering automatically. The alternative — a merchant manually formatting a size table into every product description — doesn't just look worse, it can't be bulk-updated, can't be reused, and drifts inconsistent across the catalog within a few months.
The same pattern extends cleanly to nutritional or ingredient data for food and supplement brands (a metaobject per formulation, referenced from every product using it, rendered through a consistent nutrition-label-style template), and to comparison tables across a product line (a metaobject per spec row or a metafield list per product, rendered as a genuine sortable table rather than three paragraphs of prose that nobody actually compares side by side).
The API and headless angle
Both metafields and metaobjects are fully accessible through Shopify's APIs, not just the admin UI, and this matters more than it might seem for a fairly conventional catalog. The Admin GraphQL API can create, read, update, and delete metafield and metaobject definitions and entries — this is how apps, migration scripts, and bulk-import tooling manage custom data at scale rather than through manual admin entry. The Storefront API can read metafield and metaobject values directly, which is exactly what a headless build on Hydrogen, or any custom frontend, needs to pull structured product data without scraping rendered HTML.
There's a specific setting that trips people up here: a metaobject definition has to have its storefront access explicitly set to public read before the Storefront API can see it. It's easy to build a metaobject, populate it, confirm it looks right in the admin, and then have a headless frontend query for it and get nothing back, purely because that access flag was never flipped. It's a small thing, but it's the kind of small thing that costs a debugging afternoon if nobody knows to check it.
For any brand seriously considering headless — or even one just weighing it as a future option — this is a reason to get the metafield and metaobject schema right early rather than as an afterthought. A catalog with clean, well-typed custom data behind it ports to a new frontend framework relatively cleanly. A catalog where every custom fact lives as unstructured text in a description field has to be re-parsed and re-modeled from scratch before headless is even possible.
A straight decision framework
DIY territory: a single custom fact per product, using a type that already exists in Shopify's standard definitions or a simple custom one, on a theme that supports dynamic sources for that layout. Adding a "material" text field, a "release date," a boolean "vegan" flag, or a simple rating — create the definition, fill in values, connect it through dynamic sources. No developer required, and there's no good reason to pay for this kind of work.
Gray zone, worth a scoping conversation: metaobjects that need to be referenced across multiple products, list-type metafields that need to render as anything more structured than a plain list, or a standard theme that almost but doesn't quite support the layout you need through dynamic sources. Sometimes a theme's existing sections stretch to cover it with minor tweaks; sometimes they don't, and that's worth finding out before committing to a specific approach.
Real developer territory: any structured table pulled from a metaobject or metafield list, comparison grids, conditional rendering based on field values or product type, a metaobject schema that needs to reference other metaobjects (a fit guide that references a separate size-conversion metaobject, for instance), bulk migration of existing unstructured description data into a proper schema, or anything touching the Storefront API for a headless build. This is also where it's worth having someone think through the schema itself before any Liquid gets written — a metaobject definition that's wrong at the field level is expensive to restructure later once hundreds of entries and product references depend on it.
Getting the data layer right the first time
The catalogs that end up with genuinely useful structured data — filterable specs, consistent size guides, comparison tables that actually compare — didn't get there by accident. Someone modeled the schema deliberately before typing a single value in, thought through which resource each field should attach to, decided what belonged as a metafield versus what deserved to be its own metaobject, and built theme templates that render it properly rather than leaving well-structured admin data invisible on the storefront.
This is exactly the kind of work our Shopify Deep Engineering team does for catalogs that have outgrown the description box — designing the metafield and metaobject schema against how a brand's products actually vary from each other, building the Liquid templates or headless components that surface it correctly, and setting up the Storefront API access so the same structured data can power a future headless rebuild without being re-modeled from scratch. If your catalog has structured data trapped in unstructured text — size charts as images, specs buried in prose, comparison tables nobody built — that's a data-modeling conversation worth having before more products get added the old way and the migration only gets bigger.
If any of this sounds like your situation, talk to us. We'll tell you exactly where your revenue is leaking and what it would take to fix it. Explore Strategy & Consulting →

