Admin Block Extensions
An admin block is a sandboxed iframe the host renders inline on a merchant admin page (product, order, customer, etc.). Use blocks for UI that is always present on the page — review summaries, fulfilment status, warehouse KPIs, or anything you want the merchant to see without clicking a button. If you want a button that opens a modal on demand, use an Admin Action instead.How the Host Renders It
<AdminExtensionSlot target="..." resourceId resourceType domainSlug />
mounts a sandboxed iframe per registered extension:
GET /api/apps/admin-extensions?target=<target>&domainSlug=<slug> to
discover registered extensions, then renders one iframe per result.
Available Targets
Targets are filtered by exact string match against the wired slots in the LaunchMyStore admin. Every slot uses theadmin.<resource>.render naming
convention — your manifest’s target must match exactly. 26 admin-block
slots are currently wired (plus separate slots for admin actions
and print actions):
Resource Detail Pages
List Pages
Settings Pages
Analytics
Other
The slot string is matched exactly —
product.details.block won’t
render at admin.product-details.block.render. Always copy the target
value verbatim from the table above.Targets not in the tables above won’t render even if the API accepts the
upload — only the wired slots resolve. If you need a new target,
open a support ticket with the page and resource type you want.
Manifest
Declare admin blocks underextensions.adminExtensions[] in your app’s
app.json:
Relative URLs (e.g.
/extensions/.../iframe.html) are absolutised by the
host before being returned to the admin — you always get back an absolute
URL, so there are no domain-resolution surprises inside the iframe. Use
HTTPS for production apps; the absolutizer passes absolute URLs through
untouched and does not enforce the scheme.Iframe URL Parameters
The host appends the following query params when building the iframesrc:
For convenience, when
resourceType is product, order, or customer
the host also sets a typed alias param — productId, orderId, or
customerId respectively (mirroring the SDK useApi().data shape). These
carry the same value as resourceId. locale is not passed. Whichever
param you read, always re-resolve the resource server-side using your
session token before trusting it.Bootstrap
Initialise the App Bridge SDK with theapiKey you registered the app
under, and the base64 host from the URL:
app.dispatch(action, payload) and app.dispatchAndWait(action, payload)
take an action string and a payload object — not a {type, payload}
envelope.
Resizing the Iframe
The iframe starts at 200px. To grow it, post the resize message directly — this one is not routed throughapp.dispatch:
extensionId matches. Omit extensionId and the resize is ignored —
your iframe stays empty-looking at 200px.
A typical auto-resize hook using ResizeObserver:
App Bridge Actions (Admin host)
Admin blocks can use the full admin App Bridge action set. See App Bridge Overview for the complete reference. Common calls:Show a toast
Open a modal
Navigate
Resource picker
Session token (for backend calls)
The SDK does expose
LOADING_START / LOADING_STOP actions (dispatched
by the React useLoading hook) that draw a thin progress bar on the
admin host’s title bar. They’re for host-level affordance — inside
your block iframe, render loading skeletons in your own UI rather than
relying on the global bar.Example: Reviews Panel
Discovery API
GET /api/apps/admin-extensions?target=<target>&domainSlug=<slug> returns
all installed extensions for that target. Pass &type=admin_block to
exclude action and print-action entries that also live in
/api/apps/admin-extensions.
url and appUrl fields are server-absolutised so the admin always
receives an iframe-able HTTPS URL.
Security
Iframe sandbox
Iframe sandbox
Admin blocks render with
allow-scripts allow-same-origin allow-forms allow-popups. The bridge postMessage protocol is the only cross-frame
channel.Verify session tokens server-side
Verify session tokens server-side
Anything the iframe sends to your backend should be authorised with a
fresh session token (
app.getSessionToken()) and verified against your
app’s clientSecret server-side.Use HTTPS in production
Use HTTPS in production
Always serve
url / appUrl over HTTPS in production so the iframe
loads on an HTTPS admin. Note the install pipeline does not reject
HTTP schemes — absolute URLs are passed through as-is (and local dev
URLs may resolve to http), so treat HTTPS as your responsibility.Validate URL parameters
Validate URL parameters
resourceId and domainSlug come from the merchant’s browser. Always
re-fetch the resource server-side with the session token before
trusting it.Installing
Admin blocks are declared inapp.json; the install pipeline doesn’t write
per-handle schema files for them (unlike admin actions and print actions).
Instead, each adminExtensions[] entry is fanned out into a registry row
scoped to (appId, storeId, handle, target) so the discovery API can
return it.
Registry fan-out runs automatically on both install paths:
- OAuth install — when the merchant completes
POST /apps/oauth/tokenwithgrant_type=authorization_code, the install pipeline creates the installation, then synchronously registers everyadminExtensions[]entry from your app’s published manifest. - Direct/developer install —
POST /apps/store/install/:appIdruns the same fan-out.
(appId, storeId, handle, target) are
upserted, not duplicated. Uninstall destroys all registry rows for that
(appId, storeId) pair.
The target column accepts any string verbatim — there is no enum cap on
what you can register — but as noted above the host only renders entries
whose target matches one of the wired slot tables.
See Also
- Admin Actions — modal-iframe action buttons.
- Admin Print Actions — printable templates triggered from admin resource pages.
- App Bridge Overview — full action reference.
- Sessions & Authentication — verifying iframe calls server-side.