Skip to main content
The cart knows what Shopify’s Ajax API tells it: titles, prices, quantities, properties. It doesn’t know your metafields. A cart enricher fetches extra product or variant fields from the Storefront API and attaches them to every matching line, so you can show a delivery estimate, a “ships separately” warning, an ingredient list, or anything else you store on the product. Typical uses: per-product delivery windows, allergen or ingredient badges, a custom “low stock” flag, loyalty point multipliers, subscriber-only pricing.

Register the enricher

Three fields: Whenever the cart loads or changes, Aftersell fetches your fragment for every product or variant in the cart. The fetch is non-blocking: the cart renders immediately and re-emits cart_updated once the data lands. A slow or failing fragment never delays or breaks the cart.

Read the data

Because enrichment is asynchronous, line.metadata.delivery is undefined until the first fetch resolves. Always guard the read.

Render it in the cart

Enrichment puts the data on the line; a Custom code block in React mode draws it. Add the block as a Cart items sub-block so it renders once per line and receives that line as props.line:
Enriched values come back from the Storefront API as-is and unsanitized. Render them as text, as above, and never with dangerouslySetInnerHTML or by writing raw HTML.

Variant-level data

Set onType: 'ProductVariant' when the metafield lives on the variant rather than the product:

More than metafields

The fragment is spliced into a Storefront API query, so anything the API exposes on a Product or ProductVariant works, not just metafields:

Things to get right

  • Guard every read. metadata defaults to {} and your namespace is undefined until the fetch resolves. The cart renders before the data arrives, always.
  • Each id is its own namespace. Multiple enrichers coexist without colliding, including ones registered by other apps.
  • Metafields must be Storefront-visible. A metafield that isn’t exposed to the Storefront API returns null. Check the definition in Shopify admin if you get nothing back.
  • Keep the fragment small. It runs for every product in the cart, on every cart change. Ask for the fields you use, not everything.
  • Register at set-up time. It’s a hook, so it belongs at the top of your Initialization script.
  • Braces must balance. No outer braces around the fragment, but any nested selection needs its own matching pair. An unbalanced fragment is rejected.

Where to go next