Install
$ agentstack add skill-dragnoir-shopify-agent-skills-checkout-customization ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Checkout Customization
When to use this skill
Use this skill when:
- Building checkout UI extensions
- Adding custom fields to checkout
- Implementing payment customizations
- Creating post-purchase upsells
- Extending customer account pages
- Customizing the checkout experience
- Adding custom validation logic
Overview
Checkout customization uses extensions that are:
- Upgrade-safe - Work with Shop Pay and new features
- Performant - Run in a sandboxed environment
- Secure - Limited access for security
Extension Types
| Type | Description | | --------------------- | ---------------------------- | | Checkout UI | Add custom UI to checkout | | Post-purchase | Upsells after order | | Customer Accounts | Extend account pages | | Thank You | Customize order confirmation | | Order Status | Extend order tracking |
Getting Started
1. Create Checkout Extension
# In an existing app
shopify app generate extension
# Select: Checkout UI
2. Extension Structure
extensions/
└── checkout-ui/
├── src/
│ └── Checkout.jsx
├── locales/
│ └── en.default.json
└── shopify.extension.toml
3. Configuration
# shopify.extension.toml
api_version = "2025-01"
[[extensions]]
type = "ui_extension"
name = "Custom Checkout"
handle = "custom-checkout"
[[extensions.targeting]]
module = "./src/Checkout.jsx"
target = "purchase.checkout.block.render"
Checkout UI Extensions
Basic Extension
// src/Checkout.jsx
import {
reactExtension,
Banner,
useApi,
useTranslate,
} from "@shopify/ui-extensions-react/checkout";
export default reactExtension("purchase.checkout.block.render", () => (
));
function Extension() {
const translate = useTranslate();
return (
Thank you for shopping with us!
);
}
Extension Targets
Common checkout targets:
// Before shipping options
"purchase.checkout.shipping-option-list.render-before";
// After shipping options
"purchase.checkout.shipping-option-list.render-after";
// Payment method
"purchase.checkout.payment-method-list.render-before";
// Order summary
"purchase.checkout.cart-line-list.render-after";
// Static render (header/footer)
"purchase.checkout.header.render-after";
"purchase.checkout.footer.render-after";
// Block render (anywhere in checkout)
"purchase.checkout.block.render";
// Delivery address
"purchase.checkout.delivery-address.render-before";
Using Checkout Data
import {
useCartLines,
useTotalAmount,
useShippingAddress,
useBuyerJourney,
useCustomer,
useDiscountCodes,
} from "@shopify/ui-extensions-react/checkout";
function Extension() {
const cartLines = useCartLines();
const totalAmount = useTotalAmount();
const shippingAddress = useShippingAddress();
const customer = useCustomer();
const discountCodes = useDiscountCodes();
const total = totalAmount?.amount;
const itemCount = cartLines.reduce((sum, line) => sum + line.quantity, 0);
return (
Items in cart: {itemCount}
Total: ${total}
{customer && Welcome back, {customer.firstName}!}
);
}
UI Components
import {
Banner,
BlockStack,
InlineStack,
Text,
Button,
Checkbox,
TextField,
Select,
Image,
Divider,
Heading,
Link,
View,
Grid,
Icon,
} from "@shopify/ui-extensions-react/checkout";
function Extension() {
const [checked, setChecked] = useState(false);
const [note, setNote] = useState("");
return (
Gift Options
This is a gift
{checked && (
)}
{}}>
Cancel
{}}>Save
);
}
Custom Fields with Metafields
import {
useApplyMetafieldsChange,
useMetafield,
} from "@shopify/ui-extensions-react/checkout";
function GiftMessage() {
const [message, setMessage] = useState("");
const applyMetafieldsChange = useApplyMetafieldsChange();
const handleChange = async (value) => {
setMessage(value);
await applyMetafieldsChange({
type: "updateMetafield",
namespace: "custom",
key: "gift_message",
valueType: "string",
value,
});
};
return (
);
}
Buyer Journey Intercept
Block checkout progression with validation:
import { useBuyerJourneyIntercept } from "@shopify/ui-extensions-react/checkout";
function AgeVerification() {
const [verified, setVerified] = useState(false);
useBuyerJourneyIntercept(({ canBlockProgress }) => {
if (!verified && canBlockProgress) {
return {
behavior: "block",
reason: "Age verification required",
errors: [
{
message: "Please verify your age to continue",
},
],
};
}
return { behavior: "allow" };
});
return (
I confirm I am 21 or older
);
}
Post-Purchase Extensions
Create Post-Purchase Extension
shopify app generate extension
# Select: Post-purchase UI
Post-Purchase Upsell
// src/PostPurchase.jsx
import {
extend,
render,
useExtensionInput,
BlockStack,
Button,
Text,
Image,
Heading,
CalloutBanner,
Layout,
TextContainer,
} from "@shopify/post-purchase-ui-extensions-react";
extend("Checkout::PostPurchase::ShouldRender", async ({ storage }) => {
// Decide whether to show post-purchase
const upsellProduct = await fetchUpsellProduct();
await storage.update({ upsellProduct });
return { render: true };
});
render("Checkout::PostPurchase::Render", () => );
function App() {
const { storage, done, calculateChangeset, applyChangeset } =
useExtensionInput();
const { upsellProduct } = storage.initialData;
const handleAccept = async () => {
const changeset = await calculateChangeset({
changes: [
{
type: "add_variant",
variantId: upsellProduct.variantId,
quantity: 1,
},
],
});
await applyChangeset(changeset.token);
done();
};
const handleDecline = () => {
done();
};
return (
Add this item to your order at 20% off
{upsellProduct.title}
${upsellProduct.price} (20% off)
Add to Order
No thanks
);
}
Customer Account Extensions
// Extend customer account pages
import {
reactExtension,
Page,
Card,
BlockStack,
Text,
} from "@shopify/ui-extensions-react/customer-account";
export default reactExtension("customer-account.page.render", () => (
));
function CustomAccountPage() {
return (
Your Points: 500
Earn points with every purchase!
);
}
Localization
// locales/en.default.json
{
"welcomeMessage": "Welcome to checkout",
"giftLabel": "Gift options",
"verifyAge": "I confirm I am 21 or older"
}
// locales/fr.json
{
"welcomeMessage": "Bienvenue au paiement",
"giftLabel": "Options cadeau",
"verifyAge": "Je confirme avoir 21 ans ou plus"
}
import { useTranslate } from "@shopify/ui-extensions-react/checkout";
function Extension() {
const translate = useTranslate();
return {translate("welcomeMessage")};
}
Network Requests
import { useApi } from "@shopify/ui-extensions-react/checkout";
function Extension() {
const { sessionToken } = useApi();
const fetchData = async () => {
const token = await sessionToken.get();
const response = await fetch("https://your-app.com/api/data", {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.json();
};
// Use in useEffect or event handler
}
Testing
Local Development
# Start app with preview
shopify app dev
# Extensions will load in checkout preview
Testing in Checkout Editor
- Go to Shopify admin > Settings > Checkout
- Click "Customize"
- Add your extension block
- Preview changes
Best Practices
- Keep extensions fast - Minimize API calls
- Handle errors gracefully - Show user-friendly messages
- Support localization - Use translation files
- Test on mobile - Checkout is often mobile
- Follow design guidelines - Match Shopify's checkout style
- Use progressive enhancement - Graceful degradation
Resources
- Checkout UI Extensions
- Checkout UI Components
- Post-Purchase Extensions
- Customer Account Extensions
- Extension Targets Reference
For backend logic, see the [shopify-functions](../shopify-functions/SKILL.md) skill.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: dragnoir
- Source: dragnoir/Shopify-agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.