Using Metaobject References in Notification Templates

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.

Hi @Ariel_Lezen,

Your reading is right, and it’s a known gap rather than something you’re doing wrong. The notification variables reference documents metafields at order, line and variant level (line.product.metafields.NAMESPACE.KEY), but reference types are never resolved — you get the raw GID back, which is exactly what you’re seeing. There is an open proposal on this board that Shopify staff picked up; adding your seasonal-shipping case there is worth more than another workaround:

One push back on the snapshot objection to Flow. A sent email is already frozen in time, so a value copied at order-created time is correct for that email even though the same copy would be wrong on a storefront page. Shifting a February ship window arguably should not change what a January confirmation said.

The part worth fixing now is the silent fallthrough, not the staleness. Write the group name and month to an order metafield in Flow and render {{ metafields.custom.shipping_group_month }} directly, with no GID lookup table and no default branch. A sixth group then renders nothing instead of promising 48 hours. A blank line is a support ticket; the wrong promise is a refund.

Reference: https://help.shopify.com/en/manual/fulfillment/setup/notifications/email-variables

Hey @Ariel_Lezen :waving_hand: thanks for the detailed report.

I see where you’re coming from and this is definitely a gap that has come up before, for example here: Accessing metafield reference in notification emails?

We’re looking into it on our end, but I don’t have a timeline or guarantee to share. I’ll update this thread if anything changes on that front.