|
| 1 | +--- |
| 2 | +name: shopify-app-extensions |
| 3 | +description: "Mental models and gotchas for building Shopify app extensions across admin, checkout, POS, and customer account surfaces" |
| 4 | +metadata: |
| 5 | + author: shopify |
| 6 | + version: "1.0" |
| 7 | +--- |
| 8 | + |
| 9 | +# Shopify App Extensions |
| 10 | + |
| 11 | +## The #1 Mistake: This Is NOT React DOM |
| 12 | + |
| 13 | +Extensions render in an **isolated sandbox** via Remote DOM. There is no `document`, no `window`, no CSS, no arbitrary HTML. You cannot use `<div>`, `<span>`, `<iframe>`, or `<script>` tags. |
| 14 | + |
| 15 | +**What you write** looks like JSX (Preact by default), but **what renders** are Shopify web components (`<s-button>`, `<s-banner>`, `<s-stack>`, etc.). These components inherit merchant brand settings. You cannot override or inject CSS. |
| 16 | + |
| 17 | +```tsx |
| 18 | +// WRONG - agents generate this constantly |
| 19 | +import React from 'react'; |
| 20 | +export default function MyExtension() { |
| 21 | + return <div className="my-class"><button onClick={handleClick}>Click</button></div>; |
| 22 | +} |
| 23 | + |
| 24 | +// RIGHT - Shopify UI components only |
| 25 | +import { AdminAction, Button, Text } from '@shopify/ui-extensions-react/admin'; |
| 26 | +export default function MyExtension() { |
| 27 | + return ( |
| 28 | + <AdminAction title="My Action"> |
| 29 | + <Text>Hello</Text> |
| 30 | + <Button onPress={handlePress}>Click</Button> |
| 31 | + </AdminAction> |
| 32 | + ); |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +Key corrections: |
| 37 | +- `onClick` -> `onPress` (Shopify component API) |
| 38 | +- No `className`, no `style` props |
| 39 | +- No HTML elements — only Shopify components from `@shopify/ui-extensions-react/{surface}` |
| 40 | +- Preact is the default scaffolding, not React. The React-like API is a compatibility layer. |
| 41 | + |
| 42 | +## Extension Surfaces — Decision Guide |
| 43 | + |
| 44 | +| Surface | Use When | Target Prefix | |
| 45 | +|---------|----------|---------------| |
| 46 | +| **Admin** | CRUD workflows, resource management, merchant tools | `admin.` | |
| 47 | +| **Checkout** | Cart modifications, upsells, custom fields, payment logic | `purchase.checkout.` | |
| 48 | +| **Customer Accounts** | Post-purchase, order management, account self-service | `customer-account.` | |
| 49 | +| **POS** | In-store workflows, receipt customization | `pos.` | |
| 50 | +| **Online Store** | Theme app extensions (different model — Liquid blocks, not JS sandbox) | N/A (app blocks) | |
| 51 | + |
| 52 | +Admin sub-types: |
| 53 | +- **Admin Action**: Modal triggered from resource pages (orders, products, customers). Use for transactional workflows. |
| 54 | +- **Admin Block**: Persistent card on resource pages. Use for contextual info display. |
| 55 | +- **Admin Print Action**: Document generation with preview/print APIs. |
| 56 | + |
| 57 | +> Full target catalog: https://shopify.dev/docs/api/admin-extensions |
| 58 | +> Checkout targets: https://shopify.dev/docs/api/checkout-ui-extensions |
| 59 | +
|
| 60 | +## Hard Limits & Gotchas |
| 61 | + |
| 62 | +### Bundle Size: 64KB Compressed |
| 63 | +The compiled extension bundle must be under **64KB compressed**. The CLI generates `.metafile.json` (esbuild) to help analyze what's eating your budget. Heavy libraries will blow this limit instantly. |
| 64 | + |
| 65 | +### All Extensions Deploy Together |
| 66 | +`shopify app deploy` creates a single app version containing ALL extensions. You cannot deploy one extension independently. Removing an extension from the codebase does NOT auto-remove it from the app — explicit removal is required. |
| 67 | + |
| 68 | +### Extension-Only Apps Use Custom Distribution Only |
| 69 | +Apps with no web server (extension-only) cannot be listed on the Shopify App Store. They must use custom distribution (direct install links). |
| 70 | + |
| 71 | +### Some Extensions Require Review |
| 72 | +Certain extension types require Shopify review before release. You cannot deploy an app version containing reviewable extensions until approved. |
| 73 | + |
| 74 | +### No Direct Network Access in Some Surfaces |
| 75 | +Checkout extensions cannot make arbitrary fetch calls. Use the `fetch` API provided by the extension API, which is proxied and restricted. |
| 76 | + |
| 77 | +## Configuration: shopify.extension.toml |
| 78 | + |
| 79 | +Every extension has a `shopify.extension.toml` in its directory. This defines the extension type, targets, metafields access, and capabilities. |
| 80 | + |
| 81 | +```toml |
| 82 | +# Example: extensions/my-action/shopify.extension.toml |
| 83 | +api_version = "2025-01" |
| 84 | +[[targeting]] |
| 85 | + module = "./src/ActionExtension.tsx" |
| 86 | + target = "admin.product-details.action.render" |
| 87 | +``` |
| 88 | + |
| 89 | +> Per-type TOML schemas: https://shopify.dev/docs/apps/build/app-extensions |
| 90 | +
|
| 91 | +## CLI Workflow |
| 92 | + |
| 93 | +```bash |
| 94 | +# Scaffold a new extension (interactive — picks type and surface) |
| 95 | +shopify app generate extension |
| 96 | + |
| 97 | +# Start dev server with hot reload |
| 98 | +shopify app dev |
| 99 | + |
| 100 | +# Deploy all extensions as a new app version |
| 101 | +shopify app deploy |
| 102 | +``` |
| 103 | + |
| 104 | +The CLI knows about these extension types (from source `specifications/`): |
| 105 | +`ui_extension`, `checkout_ui_extension`, `checkout_post_purchase`, `pos_ui_extension`, `function`, `theme`, `web_pixel_extension`, `flow_action`, `flow_trigger`, `flow_template`, `payments_app_extension`, `product_subscription`, `tax_calculation`, `editor_extension_collection` |
| 106 | + |
| 107 | +## Documentation Pointers |
| 108 | + |
| 109 | +- Extensions overview: https://shopify.dev/docs/apps/build/app-extensions |
| 110 | +- Admin extensions: https://shopify.dev/docs/apps/build/admin |
| 111 | +- Admin components API: https://shopify.dev/docs/api/admin-extensions/components |
| 112 | +- Checkout extensions: https://shopify.dev/docs/api/checkout-ui-extensions |
| 113 | +- Functions (backend logic): https://shopify.dev/docs/apps/build/functions |
| 114 | +- Extension TOML config: https://shopify.dev/docs/apps/build/app-extensions/configuration |
0 commit comments