Show metaobjects
Load metaobjects from Shopify into an Astro site, at build time with a loader or in the browser with Smootify elements. Covers a paged list of one type, the metaobjects of a product metafield, a single entry, and how their fields show.
Metaobjects are structured content you keep in Shopify, such as testimonials, size charts, FAQs or store details. Smootify shows them on the site: you write one entry, and Smootify fills it and repeats it. Your client can then edit that content in Shopify, next to the products. This page covers a list of entries, the entries of a product, and a single entry.
To render the entries on the server instead, with the build loader smootifyMetaobjects({ type }), see Content. This page is about Smootify’s elements, which read the entries in the browser and always show the current ones.
Note
In Shopify, under Settings > Custom data > Metaobjects, the definition must have Storefronts access turned on. Without it, the entries never reach the site. With Active-draft status also turned on, entries saved as draft stay off the site until you make them active.
Three ways to load them, each a section below:
| Way | Element and what it needs | Pages |
|---|---|---|
| A list of one type | smootify-metaobjects with data-type, the definition’s type | yes, data-limit entries at a time |
| The metaobjects of a product | smootify-metaobjects with data-type set to metafield. and the metafield’s namespace and key, and data-product-id | yes, like a list of one type |
| One entry | smootify-metaobject on its own, with data-type and data-handle (or data-id) | no; when the entry does not exist, the element is removed |
Two names you need from Shopify. The type of the definition, such as testimonial, shown on the definition’s page. And the key of each field, such as author_name for a field called “Author name”. Here they are on a testimonial definition, with its entries and what the page shows:
In the Shopify admin and on the page:
- Settings > Custom data > Metaobjects: the definition Testimonial, type
testimonial, with the fields Author name (keyauthor_name, single line text), Quote (keyquote, multi-line text) and Photo (keyphoto, file). Storefronts access on; Active-draft status on. - Content > Metaobjects > Testimonial: the entries. Anna R. and Marco B. are active; Lena K. is a draft, so it stays off the site until it is made active.
- In the markup, inside
smootify-metaobject:metaobject="author_name"shows Anna R.,metaobject="quote"her quote,metaobject="photo"her photo. The attribute takes the key, not the field’s name.
1. A list of one type
Write the element smootify-metaobjects with the attribute data-type set to the type. Inside it, write the element smootify-metaobject: the template of one entry.
<smootify-metaobjects data-type="testimonial" data-limit="6">
<div>
<smootify-metaobject>
<div metaobject="author_name">Name</div>
<div metaobject="quote">Quote</div>
</smootify-metaobject>
</div>
<empty-state>No testimonials yet</empty-state>
<button data-action="load-more">Load more</button>
</smootify-metaobjects>- The template. Smootify copies the first
smootify-metaobjectonce per entry, and removes the others you wrote. The copies go next to it, so put it in adivyou style as a grid or a list. data-limitsets how many entries load at a time, 10 by default.- Pages. A
buttonwithdata-action="next"ordata-action="prev"shows the next or the previous page in place of the current one.data-action="load-more"adds the next entries under the ones shown. Use next and previous, or load more, not both. Each button is hidden when there is no page to go to. - Nothing to show. The element
empty-stateshows while the list is empty.
While it works, smootify-metaobjects has the classes is-loaded, is-empty, has-next and has-prev, which you can style in the component’s CSS. See metaobject list attributes.
The example project has this list as the component content/MetaobjectList.astro: see Write components.
2. The metaobjects of a product or a customer
A product metafield that is a list of metaobjects, such as custom.features, can feed the same list. On the product page:
- set
data-typetometafield.followed by the metafield’s namespace and key, such asmetafield.custom.features; - add
data-product-idwith the product’sshopifyId.
<smootify-metaobjects data-type="metafield.custom.features" data-product-id={product.shopifyId}>
<smootify-metaobject><div metaobject="title">Feature</div></smootify-metaobject>
</smootify-metaobjects>It pages like a list of one type. For a few entries without pages, a metafield attribute on the product page also repeats them: see Metafields on the page.
The logged-in customer’s entries
The entries a customer created with a metaobject creator that has customer-field, such as their gift lists, are in the customer’s metafield smootify.<type>. On an account page, set data-type to metafield.smootify.gift_list and data-parent-id to customer:
<smootify-metaobjects data-type="metafield.smootify.gift_list" data-parent-id="customer" data-limit="12">
<div class="grid">
<smootify-metaobject>
<div metaobject="occasion">Occasion</div>
<h3 metaobject="title">List title</h3>
<div metaobject="date">Date</div>
<a href="/gift-list" data-handle-param="l">Open the list</a>
</smootify-metaobject>
</div>
<empty-state>No gift lists yet</empty-state>
</smootify-metaobjects>- The newest entry comes first. An entry deleted in Shopify is skipped.
- A visitor who is not logged in, or a customer with no entry yet, sees the
empty-state, and the list hasis-empty. - A link with
data-handle-paraminside the card links to that entry’s page, such as/gift-list?l=<handle>.
3. One entry
Use a smootify-metaobject on its own, outside any list, with the attributes data-type and data-handle, the handle of the entry in Shopify. data-handle can be an expression, for example to show a different size chart on each product page. data-id, with the entry’s id, works instead of the handle.
<smootify-metaobject data-type="size_chart" data-handle="shirts">
<h2 metaobject="title">Size chart</h2>
<img metaobject="image">
<div if-metaobject="notes"><div metaobject="notes">Notes</div></div>
</smootify-metaobject>When the entry does not exist, the element is removed.
The entry named in the page link. With data-handle-param, the handle comes from the page’s URL: data-handle-param="l" on the page /list?l=giulia-birthday shows the entry giulia-birthday. One page then shows every entry a form creates, such as a shared gift list, a saved configuration or a quote, with no page for each. data-id and data-handle stay the fallback when the link has no parameter; without one, or with a handle that does not exist, the element is removed.
<div class="list">
<smootify-metaobject data-type="gift_list" data-handle-param="l">
<h1 metaobject="title">Gift list</h1>
<div metaobject="message">Message</div>
</smootify-metaobject>
<div class="not-found">This list does not exist.</div>
</div>To show a message when the entry is not found, style it hidden and show it once the element is gone, with a rule in the component’s <style> such as .list:not(:has(smootify-metaobject)) .not-found { display: block; }. Anyone with the link can read the entry, so keep emails and addresses out of it. Create the metaobject definition without a display name field: Shopify then gives every entry a random handle, and nobody can guess the link of another one.
4. Show the fields
Inside a smootify-metaobject, metaobject="key" shows that field. Every field type renders, as metafields do: text, rich text, numbers, colours, dates, images and other files, links, lists, and references to products or to other metaobjects. A field without a value hides its element.
- Images take the size attributes
max-width,max-height,cropandpad-color: see image size. - Modifiers work as on metafields:
data-attr,data-digits,property,separator, anddata-pathfor a JSON field. See Metafields on the page. - Conditions.
if-metaobject="key"shows an element only when the field has a value, andunless-metaobject="key"only when it has none. Adddata-check-valueto compare with a value. See metaobject conditions. - Loading. Elements with
skeletonshimmer until the entry is filled. - Languages. Entries come in the page’s language and the visitor’s market: an entry translated in Shopify, for example with Translate & Adapt, shows translated. See Markets, currencies and languages.
How each type renders is in metafield types. The attributes are in metaobject attributes.
5. Product cards from a field
metaobject="key" on a product reference field shows the product’s title, image and link. For full product cards, with price, options, add to cart and wishlist, put a smootify-product with data-id="metaobject.<key>" inside the smootify-metaobject, where <key> is a product reference field or a list of product references of the entry. Design it as one card: Smootify repeats it once per product, in the field’s order.
<smootify-metaobject data-type="gift_list" data-handle-param="l">
<h2 metaobject="title">List title</h2>
<div class="grid">
<smootify-product data-id="metaobject.products">
<div product="title">Product title</div>
<div product="price">$0.00</div>
<smootify-add-to-cart>…</smootify-add-to-cart>
</smootify-product>
</div>
</smootify-metaobject>- Where it works. Inside a
smootify-metaobject: on its own, opened from the page link withdata-handle-param, or in each card of asmootify-metaobjectslist, each entry with its own products. Outside one, Smootify removes the card. - An empty field removes the card. A product the visitor’s market does not sell hides, as in any product list.
- A class to style.
htmlandbodygethas-metaobject-<key>when the field has products. - In a slider, the card fills the slider like the other product sources.
How many are wanted and how many are taken. When the entry keeps a quantity for each product in a JSON field, such as the quantities of a gift list made with quantities, add to the card data-requested with that field’s key. data-fulfilled names a second JSON field with what is already taken, such as gifted, which the Shopify Flow Gift list: count the gifts fills when an order is paid. Inside the card:
metaobject-quantity="requested",metaobject-quantity="fulfilled"andmetaobject-quantity="left"show the numbers, for “2 of 6 gifted” or “4 left”;- the card gets
is-partially-fulfilledwhile some are taken, thenis-fulfilledwhen none is left, and its add to cart is disabled; - the card’s quantity cannot go above what is left;
- a sold-out product still shows as sold out.
<smootify-product data-id="metaobject.products" data-requested="quantities" data-fulfilled="gifted">
<div product="title">Product title</div>
<div><span metaobject-quantity="fulfilled">0</span> of <span metaobject-quantity="requested">1</span> gifted</div>
<button type="button" data-is="direct-add-to-cart">Add to cart</button>
</smootify-product>Before you publish
Check these first
- The list disappears. It has no
data-typeor nosmootify-metaobjectinside, or, for a product list, nodata-product-id. - The list stays empty. The definition does not have Storefronts access, or
data-typeis not the definition’s type. - A field stays empty.
metaobjecthas the field’s name instead of its key: “Author name” isauthor_name. - Some entries are missing. They are saved as draft in Shopify. Make them active.
- A single entry disappears. Its handle or its type is wrong, so Shopify finds no entry.