# Show metaobjects

> Load metaobjects from Shopify straight into Webflow, without the CMS. Covers a paged list of one type, the metaobjects of a product metafield, a single entry, and how their fields show.

Status: Ready (Smootify 2.0)  
1.x page: https://docs.smootify.io/docs/metaobjects/listing  
URL: https://www.smootify.io/docs/features/metaobjects  
Updated: 2026-10-10

Metaobjects are structured content you keep in Shopify, such as testimonials, size charts, FAQs or store details. Smootify shows them on the site without the Webflow CMS: you design 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.

> [!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:

1. **Settings > Custom data > Metaobjects**: the definition Testimonial, type `testimonial`, with the fields Author name (key `author_name`, single line text), Quote (key `quote`, multi-line text) and Photo (key `photo`, file). **Storefronts** access on; **Active-draft status** on.
2. **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.
3. In Webflow, 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

Add a Custom element with the tag `smootify-metaobjects` and give it the custom attribute `data-type` with the type. Inside it, add a Custom element with the tag `smootify-metaobject`: the template of one entry.

```html
<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-metaobject` once per entry, and removes the others you designed. The copies go next to it, so put it in a Div block you style as a grid or a list.
- **`data-limit`** sets how many entries load at a time, 10 by default.
- **Pages.** Custom elements with the tag `button` and `data-action="next"` or `data-action="prev"` show 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.** A Custom element with the tag `empty-state` shows 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 as combo classes. See [metaobject list attributes](https://www.smootify.io/docs/reference/attributes/metaobjects-list).

## 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-type` to `metafield.` followed by the metafield’s namespace and key, such as `metafield.custom.features`;
- add `data-product-id`, bound to the **Shopify ID** field of the Products collection.

```html
<smootify-metaobjects data-type="metafield.custom.features" data-product-id="{Shopify ID}">
  <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](https://www.smootify.io/docs/build/metafields).

### The logged-in customer’s entries

The entries a customer created with a [metaobject creator](https://www.smootify.io/docs/features/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`:

```html
<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 has `is-empty`.
- A link with `data-handle-param` inside 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 custom attributes `data-type` and `data-handle`, the handle of the entry in Shopify. You can bind `data-handle` to a CMS field, for example to show a different size chart on each product page. `data-id`, with the entry’s id, works instead of the handle.

```html
<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 in the Designer then shows every entry a form creates, such as a shared gift list, a saved configuration or a quote, with no CMS 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.

```html
<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 custom code rule 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`, `crop` and `pad-color`: see [image size](https://www.smootify.io/docs/reference/attributes/image-size).
- **Modifiers** work as on metafields: `data-attr`, `data-digits`, `property`, `separator`, and `data-path` for a JSON field. See [Metafields on the page](https://www.smootify.io/docs/build/metafields).
- **Conditions.** `if-metaobject="key"` shows an element only when the field has a value, and `unless-metaobject="key"` only when it has none. Add `data-check-value` to compare with a value. See [metaobject conditions](https://www.smootify.io/docs/reference/conditions/metaobject).
- **Loading.** Elements with `skeleton` shimmer 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](https://www.smootify.io/docs/features/markets).

How each type renders is in [metafield types](https://www.smootify.io/docs/reference/metafield-types). The attributes are in [metaobject attributes](https://www.smootify.io/docs/reference/attributes/metaobject).

## 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.

```html
<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>
      <smootify-price><span data-prop="price">$0.00</span></smootify-price>
      <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 with `data-handle-param`, or in each card of a `smootify-metaobjects` list, 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.** `html` and `body` get `has-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](https://www.smootify.io/docs/features/metaobject-creator), 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](https://www.smootify.io/flows/gift-list-gifts) fills when an order is paid. Inside the card:

- `metaobject-quantity="requested"`, `metaobject-quantity="fulfilled"` and `metaobject-quantity="left"` show the numbers, for “2 of 6 gifted” or “4 left”;
- the card gets `is-partially-fulfilled` while some are taken, then `is-fulfilled` when 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.

```html
<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

> [!STUCK]
> - **The list disappears.** It has no `data-type` or no `smootify-metaobject` inside, or, for a product list, no `data-product-id`.
> - **The list stays empty.** The definition does not have Storefronts access, or `data-type` is not the definition's type.
> - **A field stays empty.** `metaobject` has the field's name instead of its key: "Author name" is `author_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.
