Store and landing pages
Single pages (about, offers, product landing pages) built from the live template's components.
A store page is one page at /pages/<slug>. It has no code of its own: its content places
components of the store's live template and core blocks in the template's store-page frame
(app/pages/[slug]/page.tsx, or a plain main area). A product landing page is a store page
with a productId; its product is in scope for the order form.
Layouts
content.layout picks what surrounds the page:
| Value | The page renders |
|---|---|
| absent | In the template's default layout (app/layout.tsx): the store header and footer |
blank | In the default layout with its slots left empty: the template's styles and theme, no header or footer |
<name> | In the template's app/layouts/<name>.tsx (for example a logo-only landing layout) |
GET /stores/:id/template lists the choices in layouts ([{id, title, description}]). New
product landing pages start with blank. A name the live template does not have is refused on
save (422, LAYOUT_UNKNOWN) and, after a template switch, renders in the default layout.
API
| Request | Does |
|---|---|
GET /stores/:id/pages?kind=page|landing&productId= | List pages |
POST /stores/:id/pages | Create a draft page |
PATCH /stores/:id/pages/:pageId | Change path, title, content, seo or productId with expectedVersion |
POST /stores/:id/pages/:pageId/preview | {token, path}: open <storefront><path>?pagePreview=<token> |
POST /stores/:id/pages/:pageId/publish | Make the saved version public |
POST …/unpublish, …/duplicate, DELETE … | Hide, copy, delete |
GET /stores/:id/pages/resolve?path= | Public: the published page at a path |
Every save is version-checked: a stale expectedVersion returns 409 with the current
version. The content is validated against the live template's components, store-page slots and
layouts; problems return 422 PAGE_INVALID with diagnostics.
In the app: Pages for store pages, and the Landing pages tab of a product.