Theme app blocks
The standard no-theme-write path. Add product, collection, landing, cart-progress, or cart-message surfaces in the Theme Editor.
See the standard setup →Cinch publishes a display-safe campaign contract into Shopify, then wires your markup with a small attribute-driven engine. The Cart Transform Function still decides what earns bundle pricing.
These paths share published campaign data and checkout enforcement, but they do not share the same presentation layer.
The standard no-theme-write path. Add product, collection, landing, cart-progress, or cart-message surfaces in the Theme Editor.
See the standard setup →Start from one of six full pages or four drop-in Liquid sections, then customize the real schema and markup.
Compare all ten designs →Render your own product cards, summary, and interactions against the published config and the verified data attributes.
Follow the implementation guide →The headless surface is a browser-side binding contract. It reads config already published into Shopify, owns selection state, and submits the exact cart properties the Function expects.
| Layer | Responsibility |
|---|---|
| Liquid + metafields | Resolve a published campaign and render display data. |
| Headless engine | Selection, limits, gifts, progress, and one atomic cart add. |
| Shopify Function | Revalidate the real cart and apply merge or expansion pricing. |
Point a container at the published config JSON, attach controls to numeric Shopify variant and product IDs, and let the engine maintain state and submit eligibility.
This fragment shows the contract, not campaign-resolution Liquid. The custom-page guide includes the complete resolution and eligibility pass.
{%- assign campaign_id = section.settings.campaign_id | strip -%}
{%- assign config_key = 'sfc_' | append: campaign_id -%}
{%- assign cfg = shop.metafields.cinch[config_key].value -%}
{%- assign item = cfg.disp.first -%}
{%- if cfg -%}
{%- if item -%}
<script id="cinch-config" type="application/json">
{{ cfg | json }}
</script>
<section data-cinch="cinch-config">
<button
type="button"
data-bundle-toggle="{{ item.id }}"
data-bundle-product="{{ item.pid }}"
aria-pressed="false"
>
Add {{ item.t | escape }}
</button>
<p><span data-bundle-out="count">0</span> items selected</p>
<p data-bundle-out="message"></p>
<button type="button" data-bundle-submit>Add bundle to cart</button>
</section>
{%- endif -%}
{%- endif -%}Live selection does not call the Cinch app server. Shopify cart and product endpoints are still used where the experience needs them.
Storefront totals are previews. Invalid or altered bundle hints fail closed to regular pricing rather than receiving a bundle adjustment.
The current headless asset is about 6.9 KB Brotli. Strict-CSP themes can self-host the pinned Alpine dependency used by committed designs.
These details come from the current builds, tests, and storefront adapters. They are not theme certifications or uptime claims.
| Concern | Current implementation | Evidence boundary |
|---|---|---|
| Asset size | Headless engine: 22,257 bytes raw, about 7.7 KB gzip / 6.9 KB Brotli. Theme widget: 29,426 bytes raw, about 10.1 KB gzip / 9.1 KB Brotli. | Measured current generated assets; build limits are 22,500 and 29,500 raw bytes. |
| Dependencies | No jQuery. Committed designs use Alpine 3.15.12 with a pinned SRI hash, or a self-hosted path for strict CSP. | The headless binding engine itself stays inside its checked bundle budget. |
| Network path | Live selection/configuration makes no Cinch app-server request. Shopify cart endpoints and optional product JSON still apply. | A network-allowlist test covers the storefront bundle. |
| Cart write | Parent, paid, and gift lines are sent in one atomic /cart/add.js request. | Cart replacement is remove-then-add with best-effort restore, not a Shopify transaction. |
| Theme refresh | Adapters cover Standard Storefront Events and refresh patterns used by Dawn, Horizon, Maestrooo, Archetype, and vintage themes. | This is implemented family-specific handling, not universal third-party certification. |
| Preview parity | LiquidJS preview tests and byte-parity checks compare committed design output with the production build path. | Automated test coverage, not an external benchmark. |