dist/codex/shopify-commerce/skills/shopify-checkout-ui/SKILL.md
Build Shopify checkout UI extensions — extension targets, UI primitives, Preact/Remote DOM rendering, checkout APIs, metafield access, post-purchase extensions, and thank-you page customization. Use when customizing Shopify checkout.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins shopify-checkout-uiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fetch live docs:
https://shopify.dev/docs/apps/build/checkout for checkout extensionssite:shopify.dev checkout ui extension targets for available targetssite:shopify.dev checkout ui components for UI primitivesClient-side extensions that add UI to Shopify's checkout:
Important: You cannot replace Shopify's checkout — only extend it at designated points.
Locations where extensions can render:
purchase.checkout.block.render — general block in checkoutpurchase.checkout.header.render-after — after checkout headerpurchase.checkout.footer.render-after — after checkout footerpurchase.checkout.contact.render-after — after contact infopurchase.checkout.shipping-option-list.render-after — after shipping optionspurchase.checkout.payment-method-list.render-after — after payment methodspurchase.checkout.actions.render-before — before pay buttonpurchase.thank-you.block.render — block on thank-you pagecustomer-account.order-status.block.render — block on order statuspurchase.post-purchase.render — full-page post-purchase upsellpurchase.post-purchase.should-render — decide whether to show post-purchaseCheckout extensions use Shopify's UI components (NOT Polaris, NOT HTML):
| Component | Purpose |
|-----------|---------|
| Banner | Information/warning/error messages |
| BlockStack | Vertical layout |
| Button | Action buttons |
| Checkbox | Boolean input |
| ChoiceList | Radio/checkbox groups |
| Divider | Visual separator |
| Form | Form container |
| Heading | Section headings |
| Icon | Icons |
| Image | Images |
| InlineStack | Horizontal layout |
| Link | Navigation links |
| Select | Dropdown selection |
| Text | Text content |
| TextBlock | Block of text |
| TextField | Text input |
extensions/checkout-ui/
├── src/
│ └── Checkout.tsx # Extension component
├── shopify.extension.toml # Configuration
├── locales/
│ └── en.default.json # Translations
└── package.json
api_version = "2025-01"
[[extensions]]
name = "Custom Checkout Banner"
handle = "custom-checkout-banner"
type = "ui_extension"
[[extensions.targeting]]
module = "./src/Checkout.tsx"
target = "purchase.checkout.block.render"
import {
Banner,
useExtensionApi,
useCartLines,
useApplyCartLinesChange,
reactExtension,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <CheckoutBanner />,
);
function CheckoutBanner() {
const { extension } = useExtensionApi();
const cartLines = useCartLines();
const applyCartLinesChange = useApplyCartLinesChange();
const itemCount = cartLines.reduce((sum, line) => sum + line.quantity, 0);
if (itemCount < 3) {
return (
<Banner status="info">
Add {3 - itemCount} more item(s) for free shipping!
</Banner>
);
}
return null;
}
| Hook | Purpose |
|------|---------|
| useCartLines() | Current cart line items |
| useApplyCartLinesChange() | Modify cart lines |
| useShippingAddress() | Shipping address |
| useBuyerJourney() | Intercept checkout progression |
| useAppMetafields() | Read app metafields |
| useCheckoutToken() | Checkout session token |
| useCurrency() | Current currency |
| useLocalizationCountry() | Customer country |
| useExtensionApi() | Full extension API |
useBuyerJourney() to validate before checkout progressionshopify app dev and a development store checkoutFetch the Shopify checkout UI extensions docs for exact component APIs, available hooks, and extension target names before implementing.
development
Build with Spree's headless Next.js storefront — the official `spree/storefront` repo (Next.js 16 App Router with Server Actions and Turbopack, React 19 Server Components, Tailwind CSS 4, TypeScript 5, `@spree/sdk`, Sentry), server-only auth (httpOnly JWT cookies + publishable key), MeiliSearch faceted catalog, one-page checkout with Apple/Google Pay/Klarna/Affirm/SEPA, multi-region market routing, GA4 + JSON-LD SEO, and Vercel/Docker deployment. Use when forking or customizing the storefront, or evaluating headless adoption.
tools
Build Spree extensions as Rails engines — gem scaffolding, `bin/rails g spree:extension`, mounting routes/migrations/assets, the modern `prepend` decorator pattern (`*_decorator.rb` with `self.prepended(base)`), generators (`spree:model_decorator`, `spree:controller_decorator`), the four customization surfaces in preference order (Events > Webhooks > Dependencies > Decorators), Spree::Dependencies for swapping service objects, gem release/versioning, and the deprecated Deface engine. Use when building a reusable Spree extension or adding non-trivial customization to an app.
development
Build with Spree's event bus and Webhooks 2.0 — `Spree::Events` publication, `Spree::Subscriber` DSL with `subscribes_to` and `on`, wildcard matching, lifecycle events (`{model}.created/.updated/.deleted` via `publishes_lifecycle_events`), the canonical event catalog (order.*, payment.*, shipment.*, product.*), Webhooks 2.0 endpoints, HMAC-SHA256 signing (`X-Spree-Webhook-Signature`), exponential-backoff retries, and Sidekiq job orchestration. Use when wiring event-driven business logic, building webhook consumers, or replacing ActiveSupport callback chains.
tools
Cross-cutting Spree development patterns — the customization preference hierarchy (Events > Webhooks > Dependencies > Decorators), `Spree::Dependencies` service-object swapping, the `_decorator.rb` + `prepend` + `self.prepended` idiom, idempotent subscribers and webhook receivers, multi-store scoping discipline, prefixed IDs, calculator polymorphism (shipping/promotion/tax share the base), service-object composition with `dry-monads` or simple results, why to avoid `class_eval` reopening and Deface, and Spree-on-Rails idioms (Hotwire/Turbo Stimulus, ActiveStorage, Action Cable, Sidekiq). Use when designing the architecture of a Spree extension or solving cross-cutting concerns.