Storefront Sandbox Extensions
Storefront Sandbox Extensions
Sandbox mode lets your JavaScript run inside an isolated <iframe sandbox="allow-scripts"> on the storefront. The iframe cannot access the host page's DOM, cookies, or localStorage.
How It Works
- Your extension specifies
mode: "sandbox"with asandbox_url - The storefront loads your URL in a hidden iframe
- Your code sends
selorax:readywhen initialized - The host sends
selorax:initwith page context - You either:
- Send
selorax:renderwith a JSON UI tree (host renders it natively using StorefrontRenderer) - Send
selorax:resizewith a height (host shows the iframe visibly at that height)
- Send
PostMessage Protocol
Your App → Host
| Message Type | Data | Description |
|---|---|---|
selorax:ready | — | Signal that your app is loaded |
selorax:render | { ui: <JSON tree> } | Send a JSON UI tree for native rendering |
selorax:resize | { height: 300 } | Show the iframe at this height |
selorax:toast | { message, type, duration } | Show a toast notification |
selorax:navigate | { url } | Navigate the page (http/https/relative only) |
selorax:open_link | { url } | Open URL in new tab |
selorax:close | — | Hide this extension |
Host → Your App
| Message Type | Data | Description |
|---|---|---|
selorax:init | { context, extension, environment } | Initial context + extension info |
selorax:context_update | { context } | Updated context (e.g., after cart change) |
Example
// Your sandbox app
window.addEventListener("message", (event) => {
const { type, data } = event.data || {};
if (type === "selorax:init") {
const { context } = data;
// Option 1: Send a JSON UI tree for native rendering
parent.postMessage({
type: "selorax:render",
data: {
ui: {
type: "Card",
props: { title: "Product Reviews" },
children: [
{ type: "Rating", props: { value: 4.5, count: 128 } },
{ type: "Text", props: { content: `Reviews for product ${context.product_id}` } }
]
}
}
}, "*");
// Option 2: Show your own UI in the iframe
// parent.postMessage({ type: "selorax:resize", data: { height: 400 } }, "*");
}
});
// Signal ready
parent.postMessage({ type: "selorax:ready" }, "*");Security
- Iframe uses
sandbox="allow-scripts"— noallow-same-origin - Your app cannot access the store's cookies, localStorage, or DOM
- Origin verification: host only accepts messages from your
sandbox_urlorigin - URL validation:
selorax:navigateonly allowshttp://,https://, and/URLs —javascript:is blocked - 15-second ready timeout with retry option
Actions in Rendered UI
When your sandbox sends a selorax:render tree, button actions within that tree are handled by the host's StorefrontSlot action handler — including add_to_cart, call_backend, navigate, and all other action types. Your sandbox doesn't need to implement action handling for rendered trees.
Environment Field
The selorax:init message includes environment: "storefront" so your app can distinguish between dashboard and storefront contexts if the same sandbox URL is used for both.