.agent/skills/skills/shopify-development/SKILL.md
Build Shopify apps, extensions, themes using GraphQL Admin API, Shopify CLI, Polaris UI, and Liquid. TRIGGER: "shopify", "shopify app", "checkout extension", "admin extension", "POS extension", "shopify theme", "liquid template", "polaris", "shopify graphql", "shopify webhook", "shopify billing", "app subscription", "metafields", "shopify functions"
npx skillsauth add admin-baked/bakedbot-for-brands shopify-developmentInstall 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.
Use this skill when the user asks about:
IF user wants to integrate external services OR build merchant tools OR charge for features:
→ Build an App (see references/app-development.md)
IF user wants to customize checkout OR add admin UI OR create POS actions OR implement discount rules:
→ Build an Extension (see references/extensions.md)
IF user wants to customize storefront design OR modify product/collection pages:
→ Build a Theme (see references/themes.md)
IF user needs both backend logic AND storefront UI: → Build App + Theme Extension combination
Install CLI:
npm install -g @shopify/cli@latest
Create and run app:
shopify app init # Create new app
shopify app dev # Start dev server with tunnel
shopify app deploy # Build and upload to Shopify
Generate extension:
shopify app generate extension --type checkout_ui_extension
shopify app generate extension --type admin_action
shopify app generate extension --type admin_block
shopify app generate extension --type pos_ui_extension
shopify app generate extension --type function
Theme development:
shopify theme init # Create new theme
shopify theme dev # Start local preview at localhost:9292
shopify theme pull --live # Pull live theme
shopify theme push --development # Push to dev theme
Configure in shopify.app.toml:
[access_scopes]
scopes = "read_products,write_products,read_orders,write_orders,read_customers"
Common scopes:
read_products, write_products - Product catalog accessread_orders, write_orders - Order managementread_customers, write_customers - Customer dataread_inventory, write_inventory - Stock levelsread_fulfillments, write_fulfillments - Order fulfillmentquery GetProducts($first: Int!, $query: String) {
products(first: $first, query: $query) {
edges {
node {
id
title
handle
status
variants(first: 5) {
edges {
node {
id
price
inventoryQuantity
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
query GetOrders($first: Int!) {
orders(first: $first) {
edges {
node {
id
name
createdAt
displayFinancialStatus
totalPriceSet {
shopMoney {
amount
currencyCode
}
}
}
}
}
}
mutation SetMetafields($metafields: [MetafieldsSetInput!]!) {
metafieldsSet(metafields: $metafields) {
metafields {
id
namespace
key
value
}
userErrors {
field
message
}
}
}
Variables example:
{
"metafields": [
{
"ownerId": "gid://shopify/Product/123",
"namespace": "custom",
"key": "care_instructions",
"value": "Handle with care",
"type": "single_line_text_field"
}
]
}
import {
reactExtension,
BlockStack,
TextField,
Checkbox,
useApplyAttributeChange,
} from "@shopify/ui-extensions-react/checkout";
export default reactExtension("purchase.checkout.block.render", () => (
<GiftMessage />
));
function GiftMessage() {
const [isGift, setIsGift] = useState(false);
const [message, setMessage] = useState("");
const applyAttributeChange = useApplyAttributeChange();
useEffect(() => {
if (isGift && message) {
applyAttributeChange({
type: "updateAttribute",
key: "gift_message",
value: message,
});
}
}, [isGift, message]);
return (
<BlockStack spacing="loose">
<Checkbox checked={isGift} onChange={setIsGift}>
This is a gift
</Checkbox>
{isGift && (
<TextField
label="Gift Message"
value={message}
onChange={setMessage}
multiline={3}
/>
)}
</BlockStack>
);
}
{% comment %} Product Card Snippet {% endcomment %}
<div class="product-card">
<a href="{{ product.url }}">
{% if product.featured_image %}
<img
src="{{ product.featured_image | img_url: 'medium' }}"
alt="{{ product.title | escape }}"
loading="lazy"
>
{% endif %}
<h3>{{ product.title }}</h3>
<p class="price">{{ product.price | money }}</p>
{% if product.compare_at_price > product.price %}
<p class="sale-badge">Sale</p>
{% endif %}
</a>
</div>
In shopify.app.toml:
[webhooks]
api_version = "2026-01"
[[webhooks.subscriptions]]
topics = ["orders/create", "orders/updated"]
uri = "/webhooks/orders"
[[webhooks.subscriptions]]
topics = ["products/update"]
uri = "/webhooks/products"
# GDPR mandatory webhooks (required for app approval)
[webhooks.privacy_compliance]
customer_data_request_url = "/webhooks/gdpr/data-request"
customer_deletion_url = "/webhooks/gdpr/customer-deletion"
shop_deletion_url = "/webhooks/gdpr/shop-deletion"
pageInfo.endCursorimg_url filterIF you see rate limit errors:
→ Implement exponential backoff retry logic
→ Switch to bulk operations for large datasets
→ Monitor X-Shopify-Shop-Api-Call-Limit header
IF authentication fails: → Verify the access token is still valid → Check that all required scopes were granted → Ensure OAuth flow completed successfully
IF extension is not appearing:
→ Verify the extension target is correct
→ Check that extension is published via shopify app deploy
→ Confirm the app is installed on the test store
IF webhook is not receiving events: → Verify the webhook URL is publicly accessible → Check HMAC signature validation logic → Review webhook logs in Partner Dashboard
IF GraphQL query fails: → Validate query against schema (use GraphiQL explorer) → Check for deprecated fields in error message → Verify you have required access scopes
For detailed implementation guides, read these files:
references/app-development.md - OAuth authentication flow, GraphQL mutations for products/orders/billing, webhook handlers, billing API integrationreferences/extensions.md - Checkout UI components, Admin UI extensions, POS extensions, Shopify Functions for discounts/payment/deliveryreferences/themes.md - Liquid syntax reference, theme directory structure, sections and snippets, common patternsscripts/shopify_init.py - Interactive project scaffolding. Run: python scripts/shopify_init.pyscripts/shopify_graphql.py - GraphQL utilities with query templates, pagination, rate limiting. Import: from shopify_graphql import ShopifyGraphQLAPI Version: 2026-01 (quarterly releases, 12-month deprecation window)
testing
--- name: executive-brief description: Produce a concise executive brief or portfolio digest for a super user or operator — use when summarizing multi-account performance, cross-org anomalies, top actions needed, or weekly business status for leadership review. Trigger phrases: "executive summary", "weekly brief", "portfolio digest", "top actions this week", "what needs my attention", "board update", "cross-account summary". version: 0.1.0 owner: platform agent_owner: pops allowed_roles: - sup
development
--- name: anomaly-to-action-memo description: Interpret a detected anomaly or signal and produce a decision-ready action memo — use when an alert, metric deviation, or operational signal needs to be turned into a prioritized recommendation with evidence, owner, and next step. Trigger phrases: "what does this anomaly mean", "something looks off", "explain this alert", "revenue is down", "traffic dropped", "flag this for review", "what should we do about this". version: 0.1.0 owner: ops-intelligen
testing
--- name: brand-voice description: Apply BakedBot brand voice standards to any customer-facing content — use when generating or reviewing copy that must match a dispensary or brand's approved tone, language patterns, and messaging constraints. Trigger phrases: "does this match our voice", "write in our brand voice", "on-brand copy", "brand guidelines", "tone check". version: 0.1.0 owner: platform agent_owner: craig allowed_roles: - super_user - dispensary_operator - brand_operator outputs:
testing
--- name: sell-through-partner-analysis description: Analyze which retail dispensary partners are selling through a grower's products effectively, identify top performers and laggards, and produce a prioritized partner action plan. Use when a grower wants to know where their products move fastest, which partners need attention, and where to focus wholesale sales effort. Trigger phrases: "which partners are selling our product", "sell-through analysis", "partner performance", "where is inventory