Skip to main content

Showing a Merchant-Selected Product

A Section that always shows one specific product picked by the merchant - a "Featured Product" spotlight - rather than one row of a product list (that's what Product List Item Display Card is for) or the active product on the PDP (that's Product Information).

Settings panel

Add a product field to configurationSchema.json. This opens Shopify's native product picker in the settings panel:

configurationSchema.json
[
{
"label": "Product",
"name": "product",
"type": "product"
}
]

Once the merchant picks a product, data.product resolves to a full ShopifyProduct - not just the id/handle they picked, but the same shape (title, description, images, variants, actions) documented on Product List Item Display Card.

Example

import React from 'react';
import { Flexbox, Image, Text, Button } from '@evlop/native-components';
import { Money, CustomBlock } from '@evlop/shopify';

const FeaturedProduct: CustomBlock.Section = ({ data }) => {
if (data?.product?.loading) return <Text p="md">Loading product...</Text>;
if (!data?.product) return <Text p="md">No product selected.</Text>;

const { product } = data;

return (
<Flexbox flexDirection="column" alignItems="center" gap={10} p="md">
<Image src={product.images[0].src} aspectRatio={1} width="100%" borderRadius={8} />
<Text fontSize="xl" fontWeight="Bold" textAlign="center">{product.title}</Text>
<Text textAlign="center" numberOfLines={2}>{product.description}</Text>
<Money price={product.variants[0].price} fontWeight="Bold" />
<Button action={product.actions.addToCart}>Add to Cart</Button>
</Flexbox>
);
};

export default FeaturedProduct;

How it works

  • Guard both states before rendering. data.product?.loading while the picked product is still resolving, then !data.product for when no product has been picked yet (the field is optional/unset) - two different empty states, both worth their own message rather than letting the rest of the component crash on a missing product. This { loading: true } placeholder is specific to a product configurationSchema field resolving - it's a different shape from the { isLoading: true } placeholder documented on Product List Item Display Card, which is a separate, per-list-item data path.
  • Everything else is the same styled-system component pattern used throughout these docs - Flexbox/Image/Text/Button with plain props, no extra styling library needed.
Money's prop is price, not money

Money from @evlop/shopify takes a price prop (a { amount, currencyCode } object) or, alternatively, separate amount/currencyCode string props - never a money prop. That name belongs to a different Money component, the one built into plain EDL markup. Mixing the two up (<Money money={...} /> with the @evlop/shopify import) silently renders nothing, since none of price/amount/currencyCode end up set.

Need more than one product? See Showing Several Merchant-Selected Products.