Storefront API
Content & regions
Menus and pages are classic CMS reads. Regions are the interesting part: named slots of merchant-editable block JSON that your code renders wherever it wants — the visual builder edits them, your storefront stays code.
▸ GET /storefront/v1/menus/main◂ 200 OK{ "handle": "main", "items": [ { "label": "Shop", "url": "/collections/all" }, { "label": "About", "url": "/pages/about" } ] }
Page body is plain text — paragraphs split on blank lines, never HTML. Render it with your own typography and you are immune to content-borne markup by construction.
Regions
A region is a block tree in { id, type, settings, children } node shape. Merchants edit a draft in the Admin builder and publish explicitly — this endpoint always serves the published tree.
▸ GET /storefront/v1/regions/home-hero▸ X-Publishable-Key: pk_live_9f2…◂ 200 OK{ "key": "home-hero", "updatedAt": "2026-07-07T10:12:44.000Z", "blocks": [ { "id": "b1", "type": "heading", "settings": { "text": "New season, new fits", "level": 1 } }, { "id": "b2", "type": "columns", "settings": { "columns": 2 }, "children": [ { "id": "b3", "type": "image", "settings": { "src": "https://cdn…/hero.webp", "alt": "Lookbook" } }, { "id": "b4", "type": "button", "settings": { "text": "Shop tees", "href": "/collections/tees" } } ] } ]}
| Block types | Type | Description |
|---|---|---|
| heading | leaf | Text + level 1–3. |
| text | leaf | Paragraph text. |
| image | leaf | src + alt. https/relative URLs only. |
| button | leaf | Label + href. javascript: URLs are rejected at write time. |
| spacer | leaf | Vertical rhythm. |
| columns | container | The only type that carries children. |
Hard limits, enforced at write time: depth ≤ 4, ≤ 50 nodes per region, ≤ 12 children per node. Unknown types, unknown settings keys, and over-limit trees are rejected — your renderer can still treat stored content as untrusted, and every SDK renderer does.
Every SDK ships a safe renderer for this exact subset — SDKs shows <Region> (React), composables (Vue), the use:region action (Svelte), zero-JS HTML serialization (Astro), and a real-DOM mount for everything else.