Introduction
If you have ever tried to customize the Shopify checkout experience and hit a wall, you are not alone. For years, merchants were locked into a rigid, uneditable checkout flow with only a handful of cosmetic options available through the theme editor. The only way to do more was to be on Shopify Plus and edit checkout.liquid, which even then had significant limitations.
That changed with the introduction of checkout UI extensions.
Today, Shopify's extensibility model allows developers to inject fully custom UI blocks at precise, defined locations inside the checkout called extension targets. Understanding these targets is the single most important thing you need to know before you start building checkout UI extensions, because the target you choose determines where your UI appears, when it fires, and what data it has access to.
This article is a complete, developer-focused breakdown of every checkout UI extension target available in Shopify, what each one does, when to use it, and how it maps to real conversion optimization strategies.
What Are Checkout UI Extensions?
Before diving into targets, a quick recap.
Checkout UI extensions are React-based UI components built using Shopify's extension APIs. They render inside the checkout, order status, and thank-you pages in a sandboxed environment that is safe, performant, and fully compatible with Shop Pay and Shopify's native checkout flow.
They are built using:
- Shopify CLI for scaffolding and deployment
- React for component logic
- Shopify's UI component library (Polaris Checkout Components) for rendering
- shopify.extension.toml for configuration and target declaration
The key difference between checkout UI extensions and old checkout.liquid edits is that extensions are declarative and sandboxed - they cannot break the checkout, cannot access raw payment data, and are rendered by Shopify's infrastructure rather than injected arbitrarily into the DOM.
Each extension must declare one or more targets in its configuration file. The target tells Shopify exactly where to render the extension inside the checkout journey.
What Is an Extension Target?
An extension target is a named slot inside the Shopify checkout UI where an extension can render its output. Think of targets as predefined anchor points Shopify exposes specific locations in the checkout layout where third-party or custom UI is allowed to appear.
Targets follow a naming convention:
{page}.{section}.{position}
For example:
- purchase.checkout.block.render - a block rendered anywhere in the checkout page
- purchase.checkout.contact.render-after - renders after the contact/email section
- purchase.thank-you.block.render - renders on the thank-you page after purchase
Each target also determines:
- What hooks are available (e.g., can you read cart lines? Can you apply for discount codes?)
- What UI components are supported
- Whether the extension is static or dynamic
Full List of Checkout UI Extension Targets
1. purchase.checkout.block.render
Page: Checkout
Position: Flexible merchant-configurable via the Checkout Editor
Use Case: General purpose custom blocks
This is the most flexible and commonly used target. It renders a block anywhere inside the checkout page; the exact position is determined by the merchant using Shopify's drag-and-drop Checkout Editor in the admin, not hardcoded by the developer.
This target supports the full range of Shopify's UI components and has access to most checkout hooks, including cart lines, buyer identity, shipping methods, and discount codes.
When to use it:
- Trust badges and security seals
- Free shipping progress bars
- Subscription toggle options
- Custom promotional banners
- Upsell or cross-sell product blocks
Example declaration in shopify.extension.toml:
[[extensions.targeting]]
module = "./src/FreeShippingBar.jsx"
target = "purchase.checkout.block.render"
Example component:
import {
reactExtension,
BlockStack,
Text,
Banner,
} from "@shopify/ui-extensions-react/checkout";
export default reactExtension(
"purchase.checkout.block.render",
() => <FreeShippingBar />
);
function FreeShippingBar() {
return (
<Banner status="info">
<Text>Add $15 more for FREE shipping!</Text>
</Banner>
);
}
Human Intent: Merchants use this target when they want to add value-driving content to checkout without caring about the exact fixed position letting store managers control placement through the Checkout Editor is more operationally flexible.
2. purchase.checkout.contact.render-after
Page: Checkout
Position: Immediately after the contact/email input field
Use Case: Email-adjacent messaging or opt-in fields
This target renders directly below the email address field in the checkout's Contact section. It is one of the earliest touch points in the checkout flow, making it ideal for messaging that reinforces the buyer's decision right after they enter their email.
When to use it:
- SMS/email marketing opt-in checkboxes
- Account creation prompts
- Trust messaging near email ("Your data is never shared")
- Loyalty program sign-up nudges
Example:
export default reactExtension(
"purchase.checkout.contact.render-after",
() => <EmailOptIn />
);
function EmailOptIn() {
return (
<Checkbox id="email-optin">
<Text>Subscribe to exclusive offers and early access deals</Text>
</Checkbox>
);
}
Human Intent: Shoppers have just committed their email they are engaged. This is the perfect moment to capture additional consent or prompt a loyalty sign-up before purchase anxiety sets in.
3. purchase.checkout.delivery-address.render-before
Page: Checkout
Position: Immediately before the delivery address form
Use Case: Messaging or helper UI above the shipping address block
This target renders just above where the customer fills in their delivery address. It is useful for contextual information that helps customers fill in the form correctly or understand delivery options.
When to use it:
- Shipping zone notices ("We ship to all 50 states")
- Address validation warnings
- Local pickup prompts
- International shipping notices
Human Intent: Customers filling in their address often have questions - "Do you ship to my country?" or "Is my PO Box valid?" Pre-answering these reduces form abandonment.
4. purchase.checkout.delivery-address.render-after
Page: Checkout
Position: Immediately after the delivery address form
Use Case: Post-address messaging or supplemental fields
This target renders right after the delivery address block. It is a good position for delivery-related instructions or custom field collection that depends on address information.
When to use it:
- Delivery instruction text fields ("Gate code", "Leave at door")
- Address-specific promotions ("Free local delivery in your area!")
- PO Box warnings
Example:
export default reactExtension(
"purchase.checkout.delivery-address.render-after",
() => <DeliveryInstructions />
);
function DeliveryInstructions() {
const [note, setNote] = useState("");
const applyAttribute = useApplyAttributeChange();
return (
<TextField
label="Delivery Instructions (optional)"
value={note}
onChange={(val) => {
setNote(val);
applyAttribute({ key: "Delivery Note", type: "updateAttribute", value: val });
}}
/>
);
}
Human Intent: Customers who need special delivery instructions often abandon checkout when they cannot express their needs. This target directly reduces that friction.
5. purchase.checkout.shipping-option-list.render-before
Page: Checkout
Position: Before the list of shipping options
Use Case: Contextual messaging above shipping choices
This target fires above the shipping options section before the customer sees their available shipping methods. It is an ideal placement for messaging that frames how the customer thinks about shipping.
When to use it:
- Free shipping threshold reminders ("You're $5 away from free shipping!")
- Shipping speed messaging ("Orders ship within 24 hours")
- Eco-friendly shipping prompts
Human Intent: Shipping cost is the #1 reason for cart abandonment. Intercepting the customer's attention before they see the price list and pre-framing the value significantly reduces price shock.
6. purchase.checkout.shipping-option-list.render-after
Page: Checkout
Position: After the full list of shipping options
Use Case: Messaging or actions after shipping selection
Renders below all available shipping options. Useful for reinforcing the shipping choice the customer just made or offering supplementary information.
When to use it:
- Carbon-neutral shipping upgrade offers
- Shipping insurance upsells
- Estimated delivery date reinforcement
7. purchase.checkout.shipping-option-item.render-after
Page: Checkout
Position: After each individual shipping option row
Use Case: Per-option detail or enhancement
This is a more granular target - it renders after each shipping option item in the list, not after the entire list. This means if there are three shipping options, your extension renders three times (once per option).
When to use it:
- Displaying estimated delivery dates per shipping method
- Adding "Most Popular" or "Eco Choice" badges to specific options
- Showing carbon footprint info per shipping method
Example:
export default reactExtension(
"purchase.checkout.shipping-option-item.render-after",
() => <ShippingBadge />
);
function ShippingBadge() {
const shippingOption = useShippingOptionTarget();
if (shippingOption.handle === "shopify-standard-shipping") {
return <Badge tone="success">Most Popular</Badge>;
}
return null;
}
Human Intent:
Shoppers choosing between shipping methods often have no reference point for which option is "best." Per-item context, a badge, a delivery date, a trust signal dramatically reduces decision paralysis.
8. purchase.checkout.payment-method-list.render-before
Page: Checkout
Position: Before the payment method options
Use Case: Pre-payment trust signals and messaging
This target renders just above the payment method selection. Because this is the most high-anxiety moment of the checkout the moment before a customer hands over their card details it is arguably the highest-leverage position for trust and conversion messaging.
When to use it:
- Security badges ("SSL encrypted", "PCI compliant")
- Payment method icons (Visa, Mastercard, PayPal, Shop Pay)
- Money-back guarantee reminders
- "Safe & Secure Checkout" banners
Example:
export default reactExtension(
"purchase.checkout.payment-method-list.render-before",
() => <TrustBadges />
);
function TrustBadges() {
return (
<InlineLayout spacing="base" columns={["fill", "fill", "fill"]}>
<Banner status="success">š SSL Secured</Banner>
<Banner status="info">ā
30-Day Returns</Banner>
<Banner status="info">š”ļø Buyer Protection</Banner>
</InlineLayout>
);
}
Human Intent:
This is the moment of maximum purchase hesitation. Customers are thinking: "Is this safe? What if something goes wrong?" A trust badge here directly addresses those fears at the exact right moment.
9. purchase.checkout.payment-method-list.render-after
Page: Checkout
Position: After the payment method list
Use Case: Post-payment-method messaging or CTAs
Renders below all payment options. Less commonly used, but useful for supplementary payment-related content that does not interfere with the selection itself.
When to use it:
- Buy Now Pay Later education ("What is Shop Pay Installments?")
- Payment-specific promotional messaging
10. purchase.checkout.block.render (Reusable / Multi-instance)
As noted earlier, this target can be added multiple times in a single checkout; each instance is independently positionable via the Checkout Editor. This makes it the most powerful target for building modular checkout optimization suites.
11. purchase.thank-you.block.render
Page: Thank You / Order Confirmation
Position: Flexible block on the thank-you page
Use Case: Post-purchase engagement, upsells, loyalty
This target renders on the order confirmation page after a successful purchase. The customer has already paid which completely changes the psychology of this placement. There is no purchase anxiety here; instead, there is post-purchase excitement and goodwill.
When to use it:
- Post-purchase upsell offers ("Add this to your order")
- Loyalty program sign-up ("Earn points for your purchase")
- Referral program prompts ("Share with a friend, get 10% off")
- Subscription conversion ("Turn this into a subscription")
- Social sharing prompts
Example:
export default reactExtension(
"purchase.thank-you.block.render",
() => <PostPurchaseUpsell />
);
function PostPurchaseUpsell() {
return (
<BlockStack spacing="loose">
<Text size="large" emphasis="bold">
š Thank you! Would you like to add anything else?
</Text>
<Text>
Our bestselling add-on is available at 20% off for the next 10 minutes.
</Text>
<Button kind="primary">Add to My Order</Button>
</BlockStack>
);
}
Human Intent:
The customer just completed a purchase and is in a peak positive emotional state. This is the best time to deepen the relationship whether that is through an upsell, loyalty sign-up, or referral.
12. purchase.order-status.block.render
Page: Order Status Page
Position: Flexible block on the order status page
Use Case: Post-order information and engagement
The order status page is where customers track their order after it has been placed. It is a high-revisit page where customers often check it multiple times. This makes it valuable real estate for ongoing engagement.
When to use it:
- Order tracking widgets
- Customer support chat prompts
- Referral program displays
- Review request prompts ("How was your experience?")
- Related product recommendations
Human Intent: Customers revisiting the order status page are still engaged with your brand. Meeting them with useful, relevant content (tracking info, support access) builds post-purchase trust and drives repeat purchase likelihood.
Targets by Checkout Stage: A Visual Map
CHECKOUT FLOW
ā
āāā [Contact Section]
ā āāā purchase.checkout.contact.render-after
ā
āāā [Delivery Address Section]
ā āāā purchase.checkout.delivery-address.render-before
ā āāā purchase.checkout.delivery-address.render-after
ā
āāā [Shipping Options Section]
ā āāā purchase.checkout.shipping-option-list.render-before
ā āāā purchase.checkout.shipping-option-item.render-after (per item)
ā āāā purchase.checkout.shipping-option-list.render-after
ā
āāā [Payment Section]
ā āāā purchase.checkout.payment-method-list.render-before ā HIGH IMPACT
ā āāā purchase.checkout.payment-method-list.render-after
ā
āāā [Flexible Blocks ā Merchant Positioned]
ā āāā purchase.checkout.block.render ā MOST FLEXIBLE
ā
POST-PURCHASE
ā
āāā [Thank You Page]
ā āāā purchase.thank-you.block.render ā POST-PURCHASE UPSELL
ā
āāā [Order Status Page]
āāā purchase.order-status.block.render
Choosing the Right Target: Decision Guide
| Goal | Best Target |
|---|---|
| Add a trust badge near payment | purchase.checkout.payment-method-list.render-before |
| Collect a gift message or note | purchase.checkout.contact.render-after or delivery-address.render-after |
| Show free shipping progress bar | purchase.checkout.shipping-option-list.render-before |
| Add delivery date per shipping option | purchase.checkout.shipping-option-item.render-after |
| Upsell after purchase | purchase.thank-you.block.render |
| Flexible merchant-positioned block | purchase.checkout.block.render |
| Order tracking or review request | purchase.order-status.block.render |
| Email marketing opt-in | purchase.checkout.contact.render-after |
How to Declare Multiple Targets in One Extension
You can declare multiple targets in a single shopify.extension.toml file:
api_version = "2024-01"
[[extensions]]
type = "ui_extension"
name = "My Checkout Suite"
handle = "checkout-suite"
[[extensions.targeting]]
module = "./src/TrustBadges.jsx"
target = "purchase.checkout.payment-method-list.render-before"
[[extensions.targeting]]
module = "./src/FreeShippingBar.jsx"
target = "purchase.checkout.shipping-option-list.render-before"
[[extensions.targeting]]
module = "./src/PostPurchaseUpsell.jsx"
target = "purchase.thank-you.block.render"
This approach lets you ship a comprehensive checkout optimization suite as a single deployable extension package.
Important Limitations to Know
1. Shopify Plus Requirement for Checkout Targets
Most purchase.checkout.* targets are only available to Shopify Plus merchants. The thank-you page and order status targets may be available on other plans, check Shopify's official documentation for the latest plan-level access.
2. Sandbox Restrictions
Extensions cannot access the raw DOM, cannot make arbitrary external network requests, and cannot read payment card data. They operate within Shopify's sandboxed rendering environment.
3. Checkout Editor Required for block.render Positioning
The purchase.checkout.block.render target requires the merchant to position the block manually using the Checkout Editor in Shopify Admin. It will not appear until the merchant has added it to their checkout layout.
4. API Version Alignment
Always declare the correct api_version in your shopify.extension.toml. Targets and available hooks change between API versions. Use the latest stable version available at time of development.
5. One Extension Per Target Per Location
You cannot render multiple instances of the same extension in the same position. However, you can have multiple separate extensions at the same target from different apps.
Deploying Your Checkout UI Extension
# Step 1: Create a new Shopify app
npm init @shopify/app@latest
# Step 2: Generate the checkout UI extension
shopify app generate extension
# Select: Checkout UI Extension
# Step 3: Develop locally with live preview
shopify app dev
# Step 4: Deploy to production
shopify app deploy
After deployment, go to Shopify Admin ā Online Store ā Checkout to position and activate your extension in the Checkout Editor.
Best Practices for Checkout UI Extension Targets
Match the target to buyer psychology. Every position in the checkout corresponds to a specific emotional state. The email section is engagement. The shipping section is about cost sensitivity. The payment section is about trust. Match your extension's message to where the buyer's mind is at that moment.
Use purchase.checkout.block.render for flexibility. When you are not sure which position converts best, use the flexible block target and let merchants A/B test placement via the Checkout Editor.
Keep extensions lightweight. Checkout is a high-stakes flow. Every millisecond of loading time is a risk. Avoid heavy external API calls inside extensions, keep component trees shallow, and use Shopify's native UI components instead of custom CSS.
Never stack too many extensions in one section. Placing five extensions near the payment section creates visual clutter and degrades trust rather than building it. One high-quality extension per section is the standard.
Test every target on mobile. The majority of Shopify checkouts happen on mobile devices. Every extension target needs to be tested on a narrow viewport before going live.
Conclusion
Checkout UI extensions are one of the most powerful tools available to Shopify developers and merchants today but their power is directly tied to how well you understand the available extension targets.
Each target is not just a rendering slot. It is a strategic position inside a buying journey, tied to a specific emotional state, a specific piece of buyer information, and a specific conversion opportunity. Choosing the right target is the difference between an extension that converts and one that goes unnoticed.
The targets covered in this guide from purchase.checkout.contact.render-after all the way to purchase.order-status.block.render - give you complete coverage of the checkout journey, from the first keystroke to post-order follow-up.
Start with the target that addresses your biggest conversion bottleneck. Use the Checkout Editor to position it precisely. Measure the impact. Then expand from there.
The checkout is the most valuable page in your store. Checkout UI extensions are how you make every pixel of it work harder.
Frequently Asked Questions
Q: What is the difference between purchase.checkout.block.render and other targets?
A: The block.render target is merchant-positionable via the Checkout Editor. All other targets are fixed to specific positions in the checkout layout and cannot be moved by the merchant.
Q: Can I use checkout UI extensions on a non-Plus Shopify plan?
A: The thank-you page (purchase.thank-you.block.render) and order status page targets are generally available across plans. Most checkout-step targets require Shopify Plus. Always verify in Shopify's official documentation for your current plan.
Q: How many extension targets can I use in a single extension?
A: There is no strict limit. You can declare multiple targets inside a single shopify.extension.toml. However, each target must point to a separate module file.
Q: Do checkout UI extensions work with Shop Pay?
A: Yes. Shopify builds extensions to be compatible with Shop Pay. However, some extensions may have reduced visibility depending on how Shop Pay presents its own UI.
Q: Where can I find the latest list of available targets?
A: Always refer to the official Shopify developer documentation at https://shopify.dev/docs/api/checkout-ui-extensions/targets for the most current and complete list of extension targets, as new targets are added with each API version release.

