Skip to main content
Migrate to Polaris

Version 2025-07 is the last API version to support React-based UI components. Later versions use web components, native UI elements with built-in accessibility, better performance, and consistent styling with Shopify's design system. Check out the migration guide to upgrade your extension.

ProductThumbnail

The ProductThumbnail component displays small preview images representing products. Use ProductThumbnail to provide visual identification in lists, order summaries, or cards where space is constrained and quick recognition is important.

Product thumbnails provide a visual preview of items so customers can quickly identify products. For full-size images, use Image. For user profile images, use Avatar. To display multiple product images in a compact layout, use ImageGroup.

Support
Targets (25)

Configure the following properties on the ProductThumbnail component.

Anchor to accessibilityLabel
accessibilityLabel
string
Default: `''`

The alternative text that describes the product thumbnail for assistive technologies. Screen readers announce this text when they encounter the image, and it displays as a fallback if the image fails to load.

An alt property is available as an alias for compatibility with the HTML specification. When both are specified, accessibilityLabel takes precedence.

Learn more about writing effective alternative text and the alt attribute.

string

The alternative text that describes the product thumbnail for assistive technologies. Screen readers announce this text when they encounter the image, and it displays as a fallback if the image fails to load.

This property is an alias for accessibilityLabel for compatibility with the HTML specification. When both are specified, accessibilityLabel takes precedence.

Learn more about writing effective alternative text and the alt attribute.

Anchor to badge
badge
number

A number displayed as a badge on the product thumbnail, typically used to indicate the quantity of the product in a cart or order.

'small' | 'base'
Default: 'base'

The size of the product thumbnail image.

  • base: Renders the thumbnail at its standard size.
  • small: A compact thumbnail for tighter layouts.
Anchor to source
source
<string, >

The image source (either a remote URL or a local file resource).

A src property is available as an alias for this for compatibility with the HTML specification. When both are specified, source takes precedence.

Learn more about the src attribute.

<string, >

The image source (either a remote URL or a local file resource).

This property is available as an alias for source for compatibility with the HTML specification. When both are specified, source takes precedence.

Learn more about the src attribute.


Anchor to Display a product thumbnailDisplay a product thumbnail

Display a small preview image for a product. This example presents a basic product thumbnail with a source URL and a quantity badge.

Display a product thumbnail

A product thumbnail displaying a product image with a quantity badge.

Display a product thumbnail

import {
reactExtension,
ProductThumbnail,
} from '@shopify/ui-extensions-react/customer-account';

export default reactExtension(
'customer-account.page.render',
() => <Extension />,
);

function Extension() {
return (
<ProductThumbnail
source="/assets/api/checkout-extensions/checkout/components/product-thumbnail-example-code.png"
badge={2}
/>
);
}
import {extension, ProductThumbnail} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
const paymentIcon = root.createComponent(ProductThumbnail, {
source:
'/assets/api/checkout-extensions/checkout/components/product-thumbnail-example-code.png',
badge: 2,
});

root.appendChild(paymentIcon);
});

Compare available thumbnail sizes side by side. This example displays the same product at small and base sizes with labels.

Adjust the size

import {
reactExtension,
ProductThumbnail,
Text,
InlineStack,
BlockStack,
} from '@shopify/ui-extensions-react/customer-account';

export default reactExtension(
'customer-account.page.render',
() => <Extension />,
);

function Extension() {
return (
<InlineStack spacing="base" blockAlignment="center">
<BlockStack spacing="extraTight" inlineAlignment="center">
<ProductThumbnail
source="https://cdn.shopify.com/static/sample-product/House-Plant1.png"
size="small"
alt="Indoor plant"
/>
<Text appearance="subdued">small</Text>
</BlockStack>
<BlockStack spacing="extraTight" inlineAlignment="center">
<ProductThumbnail
source="https://cdn.shopify.com/static/sample-product/House-Plant1.png"
size="base"
alt="Indoor plant"
/>
<Text appearance="subdued">base</Text>
</BlockStack>
</InlineStack>
);
}
import {extension, ProductThumbnail, Text, InlineStack, BlockStack} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
const row = root.createComponent(InlineStack, {spacing: 'base', blockAlignment: 'center'});

['small', 'base'].forEach((size) => {
const thumb = root.createComponent(ProductThumbnail, {
source: 'https://cdn.shopify.com/static/sample-product/House-Plant1.png',
size,
alt: 'Indoor plant',
});
const label = root.createComponent(Text, {appearance: 'subdued'}, size);
const col = root.createComponent(BlockStack, {spacing: 'extraTight', inlineAlignment: 'center'});
col.append(thumb);
col.append(label);
row.append(col);
});

root.append(row);
});

Anchor to Display in an order summaryDisplay in an order summary

Build an order summary with product thumbnails, names, quantities, and prices. This example shows two line items inside a Section with each product displayed alongside its details.

Display in an order summary

import {
reactExtension,
ProductThumbnail,
Text,
Heading,
InlineStack,
BlockStack,
Section,
} from '@shopify/ui-extensions-react/customer-account';

export default reactExtension(
'customer-account.page.render',
() => <Extension />,
);

function Extension() {
return (
<Section>
<Heading>Order #1234</Heading>
<BlockStack spacing="base">
<InlineStack spacing="base" blockAlignment="center">
<ProductThumbnail
source="https://cdn.shopify.com/static/sample-product/House-Plant1.png"
alt="Indoor plant"
size="small"
/>
<BlockStack spacing="extraTight">
<Text emphasis="bold">Indoor Plant</Text>
<Text appearance="subdued">Qty: 1 · $24.99</Text>
</BlockStack>
</InlineStack>
<InlineStack spacing="base" blockAlignment="center">
<ProductThumbnail
source="https://cdn.shopify.com/static/images/polaris/thumbnail-wc_src.jpg"
alt="White sneakers"
size="small"
/>
<BlockStack spacing="extraTight">
<Text emphasis="bold">White Sneakers</Text>
<Text appearance="subdued">Qty: 1 · $89.00</Text>
</BlockStack>
</InlineStack>
</BlockStack>
</Section>
);
}
import {extension, ProductThumbnail, Text, Heading, InlineStack, BlockStack, Section} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
function createLineItem(src, alt, name, detail) {
const thumb = root.createComponent(ProductThumbnail, {source: src, alt, size: 'small'});
const nameText = root.createComponent(Text, {emphasis: 'bold'}, name);
const detailText = root.createComponent(Text, {appearance: 'subdued'}, detail);
const details = root.createComponent(BlockStack, {spacing: 'extraTight'});
details.append(nameText);
details.append(detailText);
const row = root.createComponent(InlineStack, {spacing: 'base', blockAlignment: 'center'});
row.append(thumb);
row.append(details);
return row;
}

const heading = root.createComponent(Heading, {}, 'Order #1234');
const items = root.createComponent(BlockStack, {spacing: 'base'});
items.append(createLineItem(
'https://cdn.shopify.com/static/sample-product/House-Plant1.png',
'Indoor plant', 'Indoor Plant', 'Qty: 1 · $24.99',
));
items.append(createLineItem(
'https://cdn.shopify.com/static/images/polaris/thumbnail-wc_src.jpg',
'White sneakers', 'White Sneakers', 'Qty: 1 · $89.00',
));

const section = root.createComponent(Section);
section.append(heading);
section.append(items);

root.append(section);
});

Handle products without images gracefully. This example shows an empty thumbnail placeholder alongside product details when no image is available.

Show an empty state

import {
reactExtension,
ProductThumbnail,
Text,
InlineStack,
BlockStack,
} from '@shopify/ui-extensions-react/customer-account';

export default reactExtension(
'customer-account.page.render',
() => <Extension />,
);

function Extension() {
return (
<InlineStack spacing="base" blockAlignment="center">
<ProductThumbnail alt="No image available" />
<BlockStack spacing="extraTight">
<Text emphasis="bold">Custom order</Text>
<Text appearance="subdued">Image unavailable</Text>
</BlockStack>
</InlineStack>
);
}
import {extension, ProductThumbnail, Text, InlineStack, BlockStack} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
const thumb = root.createComponent(ProductThumbnail, {alt: 'No image available'});
const name = root.createComponent(Text, {emphasis: 'bold'}, 'Custom order');
const label = root.createComponent(Text, {appearance: 'subdued'}, 'Image unavailable');
const details = root.createComponent(BlockStack, {spacing: 'extraTight'});
details.append(name);
details.append(label);

const row = root.createComponent(InlineStack, {spacing: 'base', blockAlignment: 'center'});
row.append(thumb);
row.append(details);

root.append(row);
});

  • Use high-quality product images: Use optimized product images that ensure visual clarity and fast loading. Maintain a consistent aspect ratio for product thumbnails to avoid distortion or stretching.
  • Maintain visual consistency: Keep a consistent visual style for product thumbnails throughout your extension. This consistency helps customers recognize and associate thumbnails with product offerings.
  • Always provide descriptive alt text: Write alt text that describes the product, such as "Blue cotton t-shirt with crew neck." Avoid generic labels like "product image" or "thumbnail."
  • Choose appropriate sizes for your context: Smaller thumbnails work better in dense layouts like lists, while larger sizes suit product-focused interfaces. Consider the customer's task and the information density when choosing a size.

  • Product thumbnails render at a fixed aspect ratio and crop non-square images to fit. Center cropping might cut off important image details near the edges.
  • Images can be loaded from remote URLs. Cross-origin images require proper CORS headers from the image host.
  • The component shows a generic placeholder when images fail to load or no source is provided. Custom placeholder graphics aren't available.

Was this page helpful?