--- name: shopify description: "Use when building or customizing a Shopify store across its three code surfaces — themes (Liquid, Online Store 2.0 sections, blocks and JSON templates), apps (Remix with the versioned GraphQL Admin API and its query-cost model), and checkout (UI extensions, Functions, Web Pixels), plus the CLI flow and checkout-extensibility migration. NOT WooCommerce or PHP stores (that is `wordpress`), NOT the React layer of a headless storefront (that is `nextjs`), NOT non-Shopify payment integrations (that is `stripe`)." tags: [shopify, liquid, ecommerce, themes, checkout, graphql, storefront] recommends: [nextjs, stripe, wordpress, api-design, seo-geo] origin: risco --- # Shopify themes, apps & checkout The single authoritative skill for building and customizing a Shopify store. The mental model: **a Shopify store is a hosted platform you extend at well-defined seams — never a server you control.** You render on the storefront with Liquid, you mutate data through the versioned GraphQL Admin API, and you customize checkout through sandboxed extensions. The platform owns hosting, the database, PCI scope, and the checkout DOM; you own only the seams. Three surfaces, three toolchains — name the surface before you write a line of code. Pinned stack (verify against shopify.dev before pinning in a repo): - **Shopify CLI 4.x** — auto-upgrades via the package manager it was installed with; skips CI, project-local installs, and major bumps. `shopify app config push` is removed; use `shopify app deploy`. - **GraphQL Admin API `2026-04`** — latest stable; supported window 2026-04 / 2026-01 / 2025-10 / 2025-07†. Each version is supported ~12 months. Pin `apiVersion` and bump quarterly. † `2025-07` is at the edge of its window — accessible only until 2026-07-16; treat it as sunsetting and do not pin it in new work. Re-check the live list at shopify.dev/docs/api/usage/versioning. - **Remix app template** (`@shopify/shopify-app-remix`, App Bridge, Polaris React). GraphQL > REST — REST Admin API is legacy; Shopify steers all new app work to GraphQL. - **Dawn** — Shopify's source-available reference theme; OS 2.0 architecture is the baseline. ## Pick your surface first Most Shopify mistakes are surface confusion — answering with a headless React build when the ask was a Liquid section, or editing `checkout.liquid` when the seam is now an extension. Branch here: | Surface | You're working on… | Tool & entry | Reference | |---|---|---|---| | **Theme** | `.liquid` files, `{% schema %}`, JSON templates, storefront rendering, merchant-editable content | `shopify theme dev` on a Dawn-based theme | `references/liquid-themes.md` | | **App** | embedded admin UI, reading/writing store data, webhooks, automation | `shopify app dev` on the Remix template + Admin GraphQL | `references/apps-graphql.md` | | **Checkout** | checkout/thank-you/order-status UI or logic, discounts, shipping, tracking | Checkout UI extensions / Functions / Web Pixels | `references/checkout-extensibility.md` | If the answer is "the React rendering layer of a headless storefront", that is `../nextjs/SKILL.md`, not this skill — Shopify is only the data seam (Storefront API) there. ## Theme surface — Online Store 2.0 architecture OS 2.0 (GA 2021, sometimes marketed "3.0") is the architecture: JSON templates + sections- everywhere + theme blocks + `@app` blocks + dynamic sources. The file map: ```text layout/theme.liquid # the HTML shell (one per theme) templates/product.json # JSON template: which sections render, in what order sections/main-product.liquid # a section: markup + {% schema %} of merchant settings sections/*.liquid # section groups (header/footer) live here too blocks/*.liquid # theme blocks (reusable, nestable) — OS 2.0 snippets/*.liquid # partials rendered via {% render %} config/settings_schema.json # global theme settings ``` **Rule: every section carries a `{% schema %}` with `presets` so merchants edit content in the theme editor without a deploy.** The why: content belongs in `section.settings` and metafields, not in code — if a merchant has to ask you to change a headline, the section is built wrong. ```liquid

Summer Sale — 20% off everything

{{ section.settings.heading | escape }}

{% schema %} { "name": "Promo banner", "settings": [ { "type": "text", "id": "heading", "label": "Heading", "default": "Summer Sale" } ], "blocks": [{ "type": "@app" }], "presets": [{ "name": "Promo banner" }] } {% endschema %} ``` The `{ "type": "@app" }` block lets merchant-installed apps drop content into your section. The Shopify Theme Store **requires** the main product and featured-product sections to support `@app` blocks. See `references/liquid-themes.md` for setting types, section groups, and dynamic sources. ## Liquid rules - **`{% render %}`, never `{% include %}`.** `render` is scoped (the snippet only sees what you pass) and cacheable; `include` leaks the parent scope and is deprecated. ```liquid {% comment %} Bad {% endcomment %} {% include 'price' %} {% comment %} Good — explicit, scoped, cacheable {% endcomment %} {% render 'price', product: product, variant: variant %} ``` - **Bound every collection loop with `limit:`** and never nest unbounded loops — storefront render cost is real and slow pages cost conversions. `{% for p in collection.products limit: 8 %}`. - **Pipe all dynamic output.** `| money` for prices (raw values render cents/locale wrong), `| escape` for any user/merchant string (XSS), `| json` when emitting data into a `