--- title: ProductThumbnail description: >- Product thumbnail is a representation of a product image. It provides a visual preview of the item, so buyers can quickly identify products. api_version: 2025-07 api_name: customer-account-ui-extensions source_url: html: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/media-and-visuals/productthumbnail md: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/media-and-visuals/productthumbnail.md --- Migrate to Polaris Version 2025-07 is the last API version to support React-based UI components. Later versions use [web components](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/polaris-web-components), native UI elements with built-in accessibility, better performance, and consistent styling with [Shopify's design system](https://shopify.dev/docs/apps/design). Check out the [migration guide](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components) 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](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/media-and-visuals/image). For user profile images, use [Avatar](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/media-and-visuals/avatar). To display multiple product images in a compact layout, use [ImageGroup](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/media-and-visuals/imagegroup). ### Support Targets (25) ### Supported targets * Customer​Account::Kitchen​Sink * [customer-account.​footer.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/footer#footer-render-after-) * [customer-account.​order-index.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-targets) * [customer-account.​order-index.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-block-) * [customer-account.​order-status.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-announcement-) * [customer-account.​order-status.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-block-) * [customer-account.​order-status.​cart-line-item.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-item-render-after-) * [customer-account.​order-status.​cart-line-list.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-list-render-after-) * [customer-account.​order-status.​customer-information.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#customer-information-render-after-) * [customer-account.​order-status.​fulfillment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#fulfillment-status-targets) * [customer-account.​order-status.​payment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#payments-and-returns-targets) * [customer-account.​order-status.​return-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#return-details-render-after-) * [customer-account.​order-status.​unfulfilled-items.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#unfulfilled-items-render-after-) * [customer-account.​order.​action.​menu-item.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-menu-item-) * [customer-account.​order.​action.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-) * [customer-account.​order.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#order-specific-full-page-) * [customer-account.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#customer-account-full-page-) * [customer-account.​profile.​addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-page-default-targets-) * [customer-account.​profile.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#announcement-) * [customer-account.​profile.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-block-) * [customer-account.​profile.​company-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#profile-page-b2b-targets-) * [customer-account.​profile.​company-location-addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-addresses-render-after-) * [customer-account.​profile.​company-location-payment.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-payment-render-after-) * [customer-account.​profile.​company-location-staff.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-staff-render-after-) * customer-account.​profile.​payment.​render-after #### Use cases * **Order details**: Display product images alongside order line items for quick identification. * **Wishlists and saved items**: Show product previews in saved product lists. * **Subscription products**: Present the products included in a recurring subscription. * **Recommendations**: Display suggested product thumbnails in upsell or cross-sell sections. *** ## Properties Configure the following properties on the ProductThumbnail component. * **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](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204) and the [`alt`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#alt) attribute. * **alt** **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](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204) and the [`alt`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#alt) attribute. * **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. * **size** **'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. * **source** **MaybeConditionalStyle\** 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`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#src) attribute. * **src** **MaybeConditionalStyle\** 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`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#src) attribute. ### MaybeConditionalStyle A type that represents a value that can be a conditional style. We highly recommend using the \`Style\` helper which simplifies the creation of conditional styles. ```ts T | ConditionalStyle ``` ### ConditionalStyle A conditional style definition that maps one or more conditions to different values. The \`default\` value is used as a fallback when none of the conditions in \`conditionals\` are satisfied. * conditionals An array of conditional values. ```ts ConditionalValue[] ``` * default The default value applied when none of the conditional values specified in \`conditionals\` are met. ```ts T ``` ### ConditionalValue A single conditional branch that pairs a set of conditions with the value to apply when those conditions are met. * conditions The conditions that must be met for the value to be applied. At least one condition must be specified. ```ts AcceptedConditions ``` * value The value that will be applied if the conditions are met. ```ts T ``` ### ResolutionCondition A condition that targets devices based on their pixel density. * resolution The minimum device pixel ratio the condition must match. ```ts Resolution ``` ### Resolution The device pixel ratio used to serve resolution-appropriate images. A value of \`1\` targets standard displays, while higher values such as \`2\` or \`3\` target high-density (Retina) displays. ```ts 1 | 1.3 | 1.5 | 2 | 2.6 | 3 | 3.5 | 4 ``` *** ## Examples ### Display 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.](https://shopify.dev/assets/assets/images/templated-apis-screenshots/checkout-ui-extensions/2025-07/productthumbnail-default-Cm6uQoyG.png) ## Display a product thumbnail ##### React ```tsx import { reactExtension, ProductThumbnail, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.page.render', () => , ); function Extension() { return ( ); } ``` ##### JS ```js 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); }); ``` ### Adjust the size Compare available thumbnail sizes side by side. This example displays the same product at `small` and `base` sizes with labels. ## Adjust the size ##### React ```tsx import { reactExtension, ProductThumbnail, Text, InlineStack, BlockStack, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.page.render', () => , ); function Extension() { return ( small base ); } ``` ##### JS ```js 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); }); ``` ### Display in an order summary Build an order summary with product thumbnails, names, quantities, and prices. This example shows two line items inside a [Section](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/layout-and-structure/card) with each product displayed alongside its details. ## Display in an order summary ##### React ```tsx import { reactExtension, ProductThumbnail, Text, Heading, InlineStack, BlockStack, Section, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.page.render', () => , ); function Extension() { return (
Order #1234 Indoor Plant Qty: 1 · $24.99 White Sneakers Qty: 1 · $89.00
); } ``` ##### JS ```js 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); }); ``` ### Show an empty state Handle products without images gracefully. This example shows an empty thumbnail placeholder alongside product details when no image is available. ## Show an empty state ##### React ```tsx import { reactExtension, ProductThumbnail, Text, InlineStack, BlockStack, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.page.render', () => , ); function Extension() { return ( Custom order Image unavailable ); } ``` ##### JS ```js 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); }); ``` *** ## Best practices * **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. *** ## Limitations * 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. ***