Metaobject references in notification templates
We sell live nursery stock, seed potatoes, and bulbs, so ship date is a property of the product category rather than of the order. Someone buys an apple tree in January, but that tree ships in April while the seeds in the same cart go out in 48 hours. We model this with a Shipping Groups metaobject holding the group name, ship-by month, and release behaviour, referenced from every product by a single metaobject_reference metafield. One entry drives the storefront pages, our seasonal release process, and merchandising.
The order confirmation is the one place it breaks. {{ line.product.metafields.custom.perishable_tier }} returns gid://shopify/Metaobject/<ID> and .value, .name, and .system.handle all come back empty, so we hardcoded a GID-to-name-and-month lookup table in the template. The grouping stays live, but everything the email says about a group is frozen in template code, and if someone adds a sixth shipping group those products silently fall through and get told their order ships in 48 hours. A dormant tree going out in January with that promise on it is a refund.
What makes this feel like a gap rather than a missing nice-to-have is that references are the entire point of the metaobject model. A plain metafield is a value on a resource, and notification templates read those fine. A reference exists so that shared content lives in one place and many products point at it, which is exactly the shape of any content that belongs to a category rather than a SKU. Denormalizing it back onto every product to make it readable in an email undoes the reason we used a metaobject in the first place. Flow can copy values onto the order at order-created time, but that means maintaining a sync job for data we already model correctly, and the copy is a snapshot, so shifting a ship window in February leaves January orders carrying the old month.
The same shape shows up well outside seasonal shipping. Lead times on made-to-order goods, care and handling instructions for perishables or cold-chain items, category-level returns and warranty terms, regional or regulatory shipping restrictions, and reusable content blocks like support hours or seasonal messaging shared across seventeen notification templates. In every one of those cases the merchant has already built the entry, and the customer needs what it says at exactly the moment the transactional email lands. Read-only hydration of metaobject_reference and list.metaobject_reference, enough to reach system.handle and the field values, would cover all of it. We have modelled this data where Shopify told us to model it. The notification template is the one surface where we have to abandon that model and retype the values by hand.