Composable Storefront Integration
Step 1: Understand What Changed
Until now, a storefront area was either written in your project's code or built from Theme Editor sections — never both. From this release, every storefront area can be progressively taken over by the Theme Editor: you mount a slot where your own markup sits today, and your markup keeps rendering untouched until a designer publishes a composition for that area. Publishing a composition replaces your markup; unpublishing it gives your markup back.
This is opt-in per area. You can mount only the header, only the account pages, or the entire storefront. Nothing changes for an area you do not mount.
Step 2: Mount a Slot
Import ChromeSlot from @akinon/pz-theme and wrap the markup you want to make composable, passing that markup as the fallback:
<ChromeSlot slug="header" fallback={<Header />} />Two rules matter in practice:
ChromeSlotis an async server component. It cannot be used inside a client component. Mount a page-body slot in that route's layout rather than in the page, passingfallback={children}. This is the only pattern that works for routes whose page is a client component.Slugs are published content keys. Once a designer saves a composition against a slug, renaming that slug orphans their content. Use the slug names in the tables below exactly as written — some carry legacy suffixes on purpose.
ChromeSlot Options
Option
What it does
slug
Required. The placeholder the editor composes into. See the slug table below.
fallback
Your existing markup. Rendered whenever no composition is published for the slug.
pageContext
The commerce data the composed blocks read (product, listing, basket, account…). Build it with the page-context helpers so field names match what the blocks expect.
className
Class for the slot wrapper. Pass "contents" when the slot replaces a direct flex or grid child, so the wrapper does not become a box of its own and break the parent layout.
fallbackClassName
Class for the fallback wrapper on the live site. Pair it with className="contents" so your markup keeps owning its own layout classes.
sticky
Pins the slot to the top of the viewport. true for the defaults, an object to override top or zIndex, false to refuse the theme setting. Left unset, a composed header slot follows the designer's sticky-menu theme setting.
emptyZoneBand
Set false only when something else on the page already offers the takeover affordance for the same slug. Two competing calls to action for one slug is worse than none.
Step 3: Identify the Canonical Placeholder Slugs
Chrome
Area
Slug
Header
header
Footer
footer
Page Bodies
Page
Slug
Homepage
theme-homepage-body
Product detail
product-page-new
Product listing
list-page-body-new
Basket
basket-page-body
Auth
auth-page-body
Register
register-page-body
Forgot password
forgot-password-body
Guest login
guest-login-body
Order success
order-success-body
Order tracking
order-tracking-body
Stores
stores-page-body
FAQ
faq-page-body
Sitemap
sitemap-page-body
Brands
brands-page-body
Flat page
flat-page-body
404 page
not-found-body
500 page
server-error-body
Account
The account shell slug renders on every account screen, so each subpage also has its own body slug. Without the per-subpage slugs, one composition would leak across orders, addresses, profile and the rest.
Screen
Slug
Account shell (all screens)
account-page-body
Account menu
account-menu
Dashboard
account-dashboard-body
Orders
account-orders-body
Order detail
account-order-detail-body
Addresses
account-address-body
Profile
account-profile-body
Change password
account-change-password-body
Change email
account-change-email-body
Coupons
account-coupons-body
Favourites
account-favourites-body
FAQ
account-faq-content
Contact
account-contact-body
Notifications
account-notifications-body
Stock alerts
account-stock-alerts-body
Step 4: Configure Composable Checkout
The checkout page is composable, but the payment internals are sealed. Payment forms, 3D Secure, agreements and place-order exist only in code and cannot be composed, restyled away or hidden. What a composition controls is placement: where the real flow, the step indicator and the summary render on the page, and what surrounds them.
Slug
Region
checkout-page-body
The full checkout body takeover. Outlet blocks placed here position the real checkout pieces.
checkout-top-body
A band above the flow, for trust content without rebuilding the page.
checkout-bottom-body
A band below the flow.
Outlet Blocks
Inside a checkout-page-body composition, three outlet blocks place the real pieces:
Outlet block
Places
checkout-flow-outlet
The real checkout flow. Also carries the composition's layout preference: one-page or step-by-step. Leaving it unset inherits your configured checkout.
checkout-steps-outlet
The step indicator.
checkout-summary-outlet
The order summary column.
Guarantees you can rely on:
If a composition contains no outlet for a piece, that piece renders in its normal place. Checkout can never lose its flow.
On a live storefront with no checkout composition published, the bridge adds no DOM at all.
Outlets only work inside the checkout body region. Placing one elsewhere does nothing.
The flow outlet has no visibility or display controls, so it is not possible to hide payment at any breakpoint.
Duplicate outlets for the same piece do not fight: the first one to mount claims the piece, the rest stay empty.
A composition cannot switch checkout between the standalone and the unified basket-and-checkout families. That stays a settings-only decision, which also makes a basket-to-checkout redirect loop impossible.
Step 5: Set the Theme Editor Origin Allowlist
The storefront now validates every message it receives from the Theme Editor against an origin allowlist, and no longer broadcasts messages to arbitrary origins. Set the editor origin on the storefront environment:
Multiple origins can be listed, separated by commas.
Localhost is trusted automatically outside production, so local development needs no configuration.
If the variable is not set in a production environment, the editor cannot attach to the preview and the storefront logs the reason.
Step 6: Review Migration Notes
The five native header starters were retired. They had no adoption and their runtime was never published. Compose the header through the header slot instead.
The checkout summary placeholder was removed. It rendered as a second full-width band under the flow and was indistinguishable from
checkout-bottom-body; the summary column is owned by client code, so a slot could never land inside it. Anything meant to sit beside the summary now belongs in thecheckout-page-body composition, arranged around the summary outlet. Projects generated by the CLI scaffold on 2.0.44 or later already reflect this.Query parameters now reach the commerce backend on v1 product detail requests. Any storefront that relied on product detail requests ignoring query strings should smoke-test variant fetches after upgrading.
Storefronts compiling against an older es5
TypeScripttarget build again from2.0.57and2.0.61. If you deferred an upgrade because of a type-check failure in the section renderer registry, it is resolved.
Last updated
Was this helpful?

