> Shopify Plus: > [Checkout UI extensions](/docs/api/checkout-ui-extensions) that render on the information and shipping and payment steps in checkout are available only to stores on a [Shopify Plus](https://www.shopify.com/plus) plan. This guide introduces UX guidelines for adding pre-purchase product offers to checkout. ## Placement Choosing the right target is key to providing a good experience. Before you start building, decide whether you want your product offer to render at a static target, a dynamic target, or whether you'll support both. To learn more about target types, refer to the [target API](/docs/api/checkout-ui-extensions/latest/apis/extensiontargets) reference. This product offer example uses the `Checkout::Dynamic::Render[OrderSummary4]` target for the following reasons: - The target keeps the line items, discounts, and money lines together, which makes it easy for customers to scan their order summary. - A product offer is considered secondary content, and should therefore be placed outside of the order summary. > Note: > On mobile, the order summary area is collapsed by default. The UI won't display the product offer until the customer expands the order summary. <figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/apps/checkout/ux-guidelines/ux-product-offer-placement-3ec34c8d58e433b4f3072d987374439d667e1a967684e21be6d0380f18ce3ced.png" class="lazyload" alt="The target and rendering location for the product offer use case" width="1816" height="856"></figure> ## Components The components to create a product offer depends on the extension's possible states. <video style="width: 100%; height: auto;" autoplay muted loop controls> <source src="/assets/apps/checkout/product-offer.webm" type="video/webm"> <source src="/assets/apps/checkout/product-offer.mp4" type="video/mp4"> </video> The product offer use case can have the following states: - Loading - Loaded (default) - Adding - Added > Note: > Added doesn't need a success banner. The addition of the item to the order summary is confirmation that the item was successfully added to the order. You can use the following components to create the states: <table> <caption>Components list for the product offer use case</caption> <tr> <th scope="col" style="width:10vw">Component</th> <th scope="col" style="width:55vw">Preview</th> <th scope="col" style="width:35vw">Tips</th> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/structure/divider"><code>Divider</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-divider.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-divider.png" alt="The Divider component, displaying as a horizontal line"></td> <td>Because the product offer will likely display in a <a href="/docs/api/checkout-ui-extensions/latest/extension-targets-overview">core checkout feature</a> such as contact information or order summary line items, include divider lines to help separate the product offer from the order summary.</td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/feedback/skeletontext"><code>SkeletonText</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-skeletontext.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-skeletontext.png" alt="The SkeletonText component, displaying as a gray shadow"></td> <td rowspan="2">To keep placement from shifting when the content loads, try to reflect the actual content’s dimensions.</td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/feedback/skeletonimage"><code>SkeletonImage</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-skeletonimage.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-skeletonimage.png" alt="The SkeletonImage component, displaying as a gray shadow"></td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/media/image"><code>Image</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-image.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-image.png" alt="The Image component, displaying the product that's being offered at checkout"></td> <td>Keep the thumbnail size the same as the thumbnail in the order summary to keep the layout consistent.</td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/titles-and-text/heading"><code>Heading</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-heading.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-heading.png" alt="The Heading component, displaying header text for the product offer that says 'You might also like'"></td> <td>If possible, allow merchants to customize the heading content.</td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/titles-and-text/text"><code>Text</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-text-description.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-text-description.png" alt="The description portion of the Text component, displaying the price of the product that's being offered at checkout"></td> <td></td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/titles-and-text/text"><code>Text</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-text-name.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-text-name.png" alt="The Text component, displaying the name of the product that's being offered at checkout"></td> <td></td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/actions/button"><code>Button</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-button.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-button.png" alt="The Button component, displaying an 'Add' button with ghost text, with regular text, and in a state that indicates the product is being added to checkout"></td> <td>Use secondary buttons here, reserving the primary button for the main call to actions like <b>Pay now</b> and <b>Next step</b>.</td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/feedback/banner"><code>Banner</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-banner.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-banner.png" alt="The Banner component, indicating that there was an issue adding the product and asking the customer to try again"></td> <td>Use banners to communicate error states.</td> </tr> </table> ## Layout When you use a nested layout, you'll need only the following structural components: <table> <caption>Components list for the product offer use case</caption> <tr> <th scope="col" style="width:10vw">Component</th> <th scope="col" style="width:55vw">Preview</th> <th scope="col" style="width:35vw">Tips</th> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/structure/blockstack"><code>BlockStack</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-blockstack.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-blockstack.png" alt="The BlockStack component in the context of a nested layout"></td> <td>You can <a href="#nesting-blockstack">nest</a> <code>BlockStack</code> components either with themselves or with other components.</td> </tr> <tr> <td><a href="/docs/api/checkout-ui-extensions/latest/components/structure/inlinelayout"><code>InlineLayout</code></a></td> <td><img srcset="/assets/apps/checkout/ux-guidelines/component-inlinelayout.png 2w" sizes="1px" src="/assets/apps/checkout/ux-guidelines/component-inlinelayout.png" alt="The InlineLayout component in the context of a nested layout"></td> <td>You can nest <code>Inline</code> components with themselves or with other components.</td> </tr> </table> ### BlockStack Use the `BlockStack` component to stack elements on top of each other vertically. <figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/apps/checkout/ux-guidelines/blockstack-spacing-1c92110712da5101bf1b1d20315051492d8c4f9ffed22b23eb14621e2c7ea60c.png" class="lazyload" alt="The vertically-oriented BlockStack component with spacing" srcset="/assets/apps/checkout/ux-guidelines/blockstack-spacing.png 2w" sizes="1px" width="auto" height="auto"></figure> #### Nesting BlockStack > Note: > `BlockStack` and `BlockLayout` components are similar to each other. `BlockLayout` enables you to specify different row sizes. With `BlockStack`, you don't need to do that. Set spacing between the divider and the content to `loose`, for consistency with the rest of checkout’s spacing. Set the spacing between the heading and the line item content to `base`. To address different spacing values, you can nest a `BlockStack` inside of another `BlockStack` component. <figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/apps/checkout/ux-guidelines/blockstack-nesting-8d445be2305a19d235cf447683109b6c325a20c137cde7ca1688caa9f121fdab.png" class="lazyload" alt="Nesting the vertically-oriented BlockStack component" srcset="/assets/apps/checkout/ux-guidelines/blockstack-nesting.png 2w" sizes="1px" width="auto" height="auto"></figure> ### InlineLayout To display products horizontally, use `InlineLayout`, and set the spacing between elements to `base`. <figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/apps/checkout/ux-guidelines/inlinelayout-spacing-b6f9dd4359c86ee55e34b27450a4a05e469a5bbba2ade468f13d10481ef5166d.png" class="lazyload" alt="The horizontally-oriented inline layout component with spacing" srcset="/assets/apps/checkout/ux-guidelines/inlinelayout-spacing.png 2w" sizes="1px" width="auto" height="auto"></figure> ## UX guidelines Adhere to the following guidelines when you're designing a product offer checkout UI extension, so that you can help merchants gain customer trust and provide a great checkout experience: ### Only show two product offers at a time Adding more than two offers can overwhelm customers, making it difficult for them to choose a product. <figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/apps/checkout/ux-guidelines/ux-guidelines-max-prod-offers-09ce5029730c2c334910e520b1448ea68f7d3ed65809ba11a1a177d111ec2ede.png" class="lazyload" alt="A product offer at checkout that displays two items" srcset="/assets/apps/checkout/ux-guidelines/ux-guidelines-max-prod-offers.png 2w" sizes="1px" width="auto" height="auto"></figure> ### Let merchants personalize product offers Customers are more likely to respond positively to offers that relate to their shopping journey or to the items in their cart. <figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/apps/checkout/ux-guidelines/ux-guidelines-personalize-prod-offers-a1769bb098b87b6de70ece62fb93a63a30a363942e488cb2f6e385b090886496.png" class="lazyload" alt="A product offer at checkout that is related to what the customer is purchasing" srcset="/assets/apps/checkout/ux-guidelines/ux-guidelines-personalize-prod-offers.png 2w" sizes="1px" width="auto" height="auto"></figure> ### Only show necessary information Make it easy for customers to process offer information by only showing what's most relevant. For example, if supporting information like a product description is required, then progressively reveal it to customers at strategic moments. <video style="width: 100%; height: auto;" autoplay muted loop controls> <source src="/assets/apps/checkout/ux-guidelines-necessary-prod-offers.webm" type="video/webm"> <source src="/assets/apps/checkout/ux-guidelines-necessary-prod-offers.mp4" type="video/mp4"> </video> ## Next steps - Learn how to [offer customers additional products at checkout](/docs/apps/build/checkout/product-offers/build-a-pre-purchase-offer) that they can add to their order. - Explore [UX guidelines](/docs/apps/build/checkout/ux-for-checkout) for the entire checkout experience. - For practical guidance on how to design a user interface for the Shopify admin, refer to Shopify's [App Design Guidelines](/docs/apps/design-guidelines). - Get familiar with Polaris [accessibility](https://polaris.shopify.com/foundations/accessibility) and [content](https://polaris.shopify.com/content/merchant-to-customer) guidelines.