Online Store Widget
Events
The postMessage protocol between the widget and your page — the events the widget sends, and what each one carries.
The SDK turns the widget's postMessage events into the callbacks described in the SDK reference. If you embed a raw iframe instead, this page is the protocol you implement yourself. In general, use the SDK — it handles this for you.
Message shape
Every message has a source discriminator and a type:
{ "source": "scalarcut-embed", "type": "ready" }
- The widget posts messages with
source: "scalarcut-embed". - The parent page posts commands with
source: "scalarcut-embed-parent".
Widget → parent events
| Type | Payload | Meaning |
|---|---|---|
ready |
— | The widget has booted and is listening for commands. |
bomUpdated |
estimate object | The bill of materials changed. |
addToCartRequest |
{ lines, layoutFingerprint, layoutToken } |
The shopper clicked Add to cart. |
resize |
{ height: number } |
The widget asks for a new frame height. |
error |
error object | The widget hit an error it could not resolve itself. |
addToCartRequest
{
"source": "scalarcut-embed",
"type": "addToCartRequest",
"lines": [
{ "sku": "TILE-600-300", "qty": 5, "unit": "box" }
],
"layoutFingerprint": "…",
"layoutToken": "…"
}
The tile line is always present. When consumables-to-cart is enabled for the store, adhesive, grout, and primer lines are added as well. Add each line to your store's cart. See Cart integration for how price and stock stay authoritative in your checkout.
resize
The widget reports the height it needs. A raw-iframe integration should honour it so the frame never scrolls inside a clipped box:
window.addEventListener('message', (event) => {
const data = event.data;
if (data?.source !== 'scalarcut-embed') return;
if (data.type === 'resize') {
frame.style.height = `${data.height}px`;
}
});
Parent → widget commands
The SDK exposes these as handle methods; the raw protocol is:
| Type | Data | SDK equivalent |
|---|---|---|
setSku |
{ sku } |
handle.setSku(sku) |
exportBlueprint |
— | handle.exportBlueprint() |
requestAddToCart |
— | handle.requestAddToCart() |
frame.contentWindow.postMessage(
{ source: 'scalarcut-embed-parent', type: 'setSku', sku: 'NEXT_SKU' },
'https://embed.scalarcut.com',
);
Origin checks
Both sides check the message origin before acting. The SDK already does this; if you implement the protocol yourself, compare event.origin against the embed origin and ignore anything that does not match.