App Bridge Overview
The communication layer between your plugin iframe and the Whatalo admin — built on postMessage with strict origin validation.
The App Bridge is the JavaScript library that connects your plugin (running inside an iframe) to the Whatalo admin shell. It provides a typed, promise-based API for reading store context, triggering UI actions, and staying in sync with admin state — all without direct DOM access across the iframe boundary.
Internally it uses the browser's postMessage API with strict origin validation on both sides.
Installation
@whatalo/plugin-sdk is already included when you scaffold with whatalo init. For existing projects:
pnpm add @whatalo/plugin-sdkQuick Start
import { useAppBridge } from "@whatalo/plugin-sdk/bridge";
function MyPlugin() {
const bridge = useAppBridge();
// Wait for the handshake to complete before rendering
if (!bridge.isReady) return <div>Loading...</div>;
return (
<div>
<h1>Hello, {bridge.storeName}!</h1>
<p>
{bridge.user.email} — {bridge.user.role}
</p>
<button
onClick={() =>
bridge.toast.show("It works!", { variant: "success" })
}
>
Test Toast
</button>
</div>
);
}Available Hooks
| Hook | Use case |
|---|---|
useAppBridge() | Recommended. All-in-one access to context, actions, and billing. |
useWhataloContext() | Context data only (store, user, theme, current page). |
useWhataloAction() | Actions only (toast, navigate, modal, resize, billing). |
Use useAppBridge() unless you have a specific reason to keep context and actions separate.
For user identity in plugin UI, prefer bridge.user.email and bridge.user.role. Treat bridge.user.name as a display label only.
Message Protocol
The bridge uses four message types over postMessage:
| Type | Direction | Purpose |
|---|---|---|
whatalo:init | Host → Plugin | Sends the parent origin for secure communication |
whatalo:context | Host → Plugin | Sends store, user, theme, and current page data |
whatalo:action | Plugin → Host | Plugin requests an action (toast, navigate, modal, etc.) |
whatalo:ack | Host → Plugin | Host confirms action success or failure |
Handshake Sequence
Admin loads iframe → your appUrl is rendered
│
▼
Host sends whatalo:init (contains parentOrigin)
│
▼
Plugin stores parentOrigin, sends "ready" action
│
▼
Host responds with whatalo:context (full context payload)
│
▼
Plugin sets isReady = true → your UI rendersUntil isReady is true, all outgoing actions are queued and sent once the handshake completes.
Security Model
- Origin pinning — The plugin sends every action exclusively to the
parentOriginreceived duringwhatalo:init. It never sends to"*". - Host validation — The admin validates every incoming message's origin against the plugin's registered
appUrl. Messages from other origins are silently dropped. - Same-origin block — Plugin URLs that share origin with the admin are rejected.
- Action timeout — All actions have a 5-second timeout. If no
whatalo:ackis received, the returned promise resolves with{ success: false, error: "timeout" }.
Rate Limits
Rate limits are enforced per action type using a sliding 10-second window:
| Action | Max per 10 seconds |
|---|---|
toast | 3 |
navigate | 5 |
modal | 3 |
resize | 30 |
billing | 10 |
Requests beyond the limit are rejected with { success: false, error: "rate_limited" }.