Customer Account Extensions
Customer-account extensions are iframes injected into the customer’s account pages (/account, /orders/[orderId], /account/profile).
Use them for order tracking widgets, loyalty balances, support chat
panels, and similar customer-facing surfaces.
These are distinct from admin extensions (which target the merchant
admin UI) and from checkout extensions (which target the
unauthenticated checkout flow). They run for a logged-in customer with
the customer’s session.
Targets
| Target | Page | Wired today |
|---|---|---|
customer-account.order-status.block.render | /orders/[orderId] | ✓ live |
customer-account.dashboard.block.render | /account | ✓ live |
customer-account.order-list.block.render | /account | ✓ live |
customer-account.profile.block.render | /account/profile | ✓ live |
dashboard.block.render renders above the page header on
/account; order-list.block.render renders between the header and the
order history list on the same page; profile.block.render renders above
the “Profile” heading on /account/profile; order-status.block.render
renders on the per-order page.
The <CustomerAccountExtensionSlot target="..." /> component renders one
iframe per registered extension at the given target. It requires the
customer’s session token as bearerToken; without it the slot API returns
401 and the slot renders empty (correct secure default — extension
enumeration is gated behind authentication).
Manifest
| Field | Required | Description |
|---|---|---|
target | yes | One of the targets above. |
url | yes | Relative path (under extensions/) or absolute https URL. |
title | no | Label shown to the merchant in the apps admin. |
permissions | no | OAuth scopes the iframe needs — same vocabulary as admin extensions. |
App Bridge inside the iframe
The iframe is initialized with the App Bridge SDK just like admin extensions, but the session token represents the logged-in customer, not the merchant. Use the bundleduseApi() hook (or RestApi.create)
to make authenticated calls against /api/v1/customer/....
data via
EXTENSION_CONTEXT:
| Target | data shape |
|---|---|
order-status.block.render | { orderId, customerId } |
dashboard.block.render | { customerId } |
order-list.block.render | { customerId } |
profile.block.render | { customerId } |
Discovery
The storefront exposes:Security
- Cookies are not shared with the iframe (
SameSite=Stricton the customer session cookie). - The iframe uses session tokens signed with the app’s client secret, scoped to the customer id — your backend must verify the JWT before trusting any customer id passed in URL parameters.