Skeleton Image
SkeletonImage is used to provide a low fidelity representation of an image before it appears on the page.
Anchor to skeletonimagepropsSkeletonImageProps
- Anchor to aspectRatioaspectRatioaspectRationumbernumber
Displays the skeleton at the specified aspect ratio (fills the width of the parent container and sets the height accordingly).
- Anchor to blockSizeblockSizeblockSizeMaybeResponsiveConditionalStyle<number | `${number}%` | 'fill'>MaybeResponsiveConditionalStyle<number | `${number}%` | 'fill'>
Adjust the block size of the skeleton.
- Anchor to idididstringstring
A unique identifier for the component.
- Anchor to inlineSizeinlineSizeinlineSizeMaybeResponsiveConditionalStyle<number | `${number}%` | 'fill'>MaybeResponsiveConditionalStyle<number | `${number}%` | 'fill'>
Adjust the inline size of the skeleton.
MaybeResponsiveConditionalStyle
A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles. To learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation.
T | ConditionalStyle<T, ViewportSizeCondition>ConditionalStyle
- conditionals
An array of conditional values.
ConditionalValue<T, AcceptedConditions>[] - default
The default value applied when none of the conditional values specified in `conditionals` are met.
T
ConditionalValue
- conditions
The conditions that must be met for the value to be applied. At least one condition must be specified.
AcceptedConditions - value
The value that will be applied if the conditions are met.
T
ViewportSizeCondition
- viewportInlineSize
{ min: T; }
Preview

Examples
Basic SkeletonImage
React
import { reactExtension, SkeletonImage, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { return ( <SkeletonImage inlineSize={300} blockSize={300} /> ); }JS
import {extension, SkeletonImage} from '@shopify/ui-extensions/checkout'; export default extension('purchase.checkout.block.render', (root) => { const skeletonImage = root.createComponent(SkeletonImage, { inlineSize: 300, blockSize: 300, }); root.appendChild(skeletonImage); });Using skeleton loaders to prevent layout shifts on content load.
Description
When adding content to a layout, incorporate a skeleton loader that renders the approximate size and position of the content during loading. This will provide a seamless transition from skeleton loaders to the content, and prevent any layout shift when the resulting content loads.
React
import { reactExtension, View, BlockStack, InlineLayout, SkeletonImage, Image, Icon, SkeletonText, Text, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <LoadingStateSkeletons />, ); export const ProductThumbnail = ({ source = 'https://yourawesomeimage.com', }) => ( <View minBlockSize={64} cornerRadius="large" maxInlineSize={64} minInlineSize={64} border="base" > {source ? ( <Image fit="cover" aspectRatio={1} source={source} cornerRadius="large" /> ) : ( <View maxInlineSize={33}> <Icon source="camera" size="fill" /> </View> )} </View> ); export const LoadingStateSkeletons = () => { const loading = true; const [item1, item2] = [ { title: 'Felipe Toledo WildFire', variantTitle: 'Medium', price: '$330.00', }, { title: 'Roller', variantTitle: 'Medium', price: '$248.00', }, ]; const itemInfo = ({title, variantTitle}) => loading ? ( <> <SkeletonText>{title}</SkeletonText> <SkeletonText> {variantTitle} </SkeletonText> </> ) : ( <> <Text emphasis="bold">{title}</Text> <Text appearance="subdued"> {variantTitle} </Text> </> ); const order = (item) => ( <InlineLayout columns={['auto', 'fill', 'auto']} spacing="base" blockAlignment="center" > {loading ? ( <SkeletonImage blockSize={64} inlineSize={64} /> ) : ( <ProductThumbnail /> )} <BlockStack spacing="extraTight"> {itemInfo(item)} </BlockStack> {loading ? ( <SkeletonText>{item.price}</SkeletonText> ) : ( <Text emphasis="bold">{item.price}</Text> )} </InlineLayout> ); return ( <View maxInlineSize={400}> <BlockStack> {order(item1)} {order(item2)} </BlockStack> </View> ); };JavaScript
import { extension, BlockStack, View, InlineLayout, Image, Icon, Text, SkeletonImage, SkeletonText, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root) => { const source = 'https://yourawesomeimage.com'; const loading = true; const [item1, item2] = [ { title: 'Felipe Toledo WildFire', variantTitle: 'Medium', price: '$330.00', }, { title: 'Roller', variantTitle: 'Medium', price: '$248.00', }, ]; const thumbnail = root.createComponent( View, { minBlockSize: 64, cornerRadius: 'large', maxInlineSize: 64, minInlineSize: 64, border: 'base', }, [ source ? root.createComponent(Image, { fit: 'cover', aspectRatio: 1, source, cornerRadius: 'large', }) : root.createComponent( View, {maxInlineSize: 33}, [ root.createComponent(Icon, { source: 'camera', size: 'fill', }), ], ), ], ); const itemInfo = ({title, variantTitle}) => root.createComponent( BlockStack, { spacing: 'extraTight', }, [ loading ? (root.createComponent( SkeletonText, {}, title, ), root.createComponent( SkeletonText, {}, variantTitle, )) : (root.createComponent( Text, {}, title, ), root.createComponent( Text, {}, variantTitle, )), ], ); const order = (item) => root.createComponent( InlineLayout, { columns: ['auto', 'fill', 'auto'], spacing: 'base', blockAlignment: 'center', }, [ loading ? root.createComponent( SkeletonImage, { blockSize: 64, inlineSize: 64, }, ) : thumbnail, itemInfo(item), loading ? root.createComponent( SkeletonText, {}, item.price, ) : root.createComponent( Text, {}, item.price, ), ], ); const view = root.createComponent( View, { maxInlineSize: 400, }, [ root.createComponent(BlockStack, {}, [ order(item1), order(item2), ]), ], ); root.appendChild(view); }, );