Skip to main content

App Bridge

App Bridge is the postMessage-based SDK that brokers communication between your app’s iframe and the LaunchMyStore host page — whether that host is the admin (the admin), the checkout, or the post-purchase / order-status page. It speaks one wire protocol everywhere; what changes is which actions the host happens to wire up. The SDK package is @launchmystore/app-bridge (vanilla TS) with a thin React adapter at @launchmystore/app-bridge-react.

Installation

The SDK ships as CJS + ESM only (dist/index.js and dist/index.mjs). There is no public CDN build — if you need an inline build, build the SDK locally and serve the bundle yourself.

Quick Start

app.dispatch(action, payload) and app.dispatchAndWait(action, payload) take the action name as the first argument. Do not pass a { type, payload } envelope — the host filters on type: 'APP_BRIDGE_ACTION' plus the action field, and a {type, payload} call would post a malformed message that the host silently drops.

Core API

The App instance returned by createApp() exposes four methods:

dispatch()

dispatchAndWait()

Promise behaviour:
  • Resolves with the host’s response payload (the bare payload — not wrapped in another payload key).
  • Rejects after 10 seconds with Error('App Bridge: timeout waiting for <action> response').
  • Rejects if the host returns an error string — the SDK rejects with new Error(error), i.e. the host’s error message verbatim (no App Bridge: <action> failed: prefix).

subscribe()

getSessionToken()

Note that app.getSessionToken() is not cached — it issues a fresh SESSION_TOKEN_REQUEST on every call. Caching (return the cached token while more than 30s from expiry, otherwise refresh) lives in the SessionToken action class and the useSessionToken React hook. Use those if you want caching. See Sessions & Authentication.

Action Surface

Action names are screaming-snake-case verbs, not object types. The SDK exports helper classes for the actions below in @launchmystore/app-bridge/actions — but whether an action does anything on a given page depends on what that host has wired. The per-host pages linked from the Hosts table are the authoritative source of truth.

SDK-exposed action families

The admin host also handles USER_FETCH, CONFIG_FETCH, CONFIG_GET, ENVIRONMENT_FETCH, FEATURES_QUERY, PRINT, SHARE, SCANNER_OPEN/SCANNER_CLOSE, FULLSCREEN_ENTER/EXIT/TOGGLE, INTENT_LAUNCH, EXTENSION_CONTEXT_GET, and APP_BRIDGE_READY. These work only in admin contexts — dispatching them from a checkout or post-purchase iframe times out after 10 seconds. Note the SDK’s Features class is a local capability check and never round-trips; use raw dispatchAndWait('FEATURES_QUERY') if you want the host’s own answer.
Counts vary as the surface grows. See:

Wire Format

The protocol is small enough to implement without the SDK if you need to. The iframe posts:
The host replies:
The iframe also self-resizes via a separate message type:
Resize clamps depend on the host. Admin blocks: default 200, max 2000. Admin Action modals: default 400, max 800 (and no extensionId is echoed — the modal already knows which extension it loaded). Checkout extension slots: default 60, max 2000.

React Integration

The React adapter wraps the same SDK in a context provider plus a hook for every action family.
<AppBridgeProvider> takes a single config prop, not separate apiKey / host props. useToast() returns an object (show, success, error, warning, info), not a callable function.
The React package ships 30+ hooks — useAppBridge, useToast, useModal, useConfirmationModal, useResourcePicker, useProductPicker, useCollectionPicker, useCustomerPicker, useFilePicker, useContextualSaveBar, useDirtyState, useTitleBar, useNavigationMenu, useSessionToken, useAuthenticatedFetch, useAppQuery, useAppMutation, useRedirect, useLoading, useAppSubscription, useAppDispatch, useAppDispatchAndWait, useUser, useConfig, useEnvironment, useFeatures, useFullscreen, useLeaveConfirmation, useUnsavedChanges, usePrint, useShare, useClipboard, useCopyToClipboard, useHistory, useLifecycle (useOnFocus, useOnBlur, useOnVisible, useOnHidden), useCart. Full list with signatures: React Hooks Reference.

Resource Picker

The picker action handles the eleven entity types your app might want to let merchants choose from.
Or via the helper class for non-promise flows:

Supported resourceType values

Session Tokens

JWT payload (HS256, signed with your app’s client secret):
Tokens last 24 hours (exp = iat + 86400). The SDK refreshes automatically when the cached token is within 30s of expiry. The host endpoint is POST /api/apps/session-token proxied through the admin. Verify tokens on your backend with jsonwebtoken.verify(token, clientSecret, { audience, issuer: 'https://launchmystore.io' }) — the issuer is the full URL, and the per-token id claim is sid (not jti). See Sessions & Authentication for the full claim set and the verification recipe.

Hosts

App Bridge is the same SDK regardless of where your iframe is mounted — but the wired action set differs per host: Actions not wired on a host time out after 10s rather than throwing synchronously — so if a checkout iframe dispatches RESOURCE_PICKER_OPEN, the promise rejects ten seconds later with the timeout message.

Identifying the shop and user

The host pushes an EXTENSION_CONTEXT payload to every iframe on mount (triggered by APP_BRIDGE_READY, and on demand via EXTENSION_CONTEXT_GET). In React, read it via useApi().data; in vanilla JS, subscribe to the EXTENSION_CONTEXT action or read window.__LMS_EXTENSION_CONTEXT__ once the SDK has populated it. The host sources shop and user from your /accounts row and is populated for every authenticated admin session.

Tenant + auth (always present)

shop (mirrors app.shop)

user (mirrors app.staffMember)

app + slot context

domainSlug + shop.storeId are the two fields you should persist data against. domainSlug can change if a merchant re-keys their store; shop.storeId is immutable.

Security

The SDK only accepts messages from atob(config.host). The host only accepts messages whose payload.apiKey matches an installed app. A rogue iframe in a different origin cannot forge a message that the host will act on.
Session tokens are signed on the host’s server using the client secret stored against your app row. The iframe only ever sees the signed JWT — never the secret.
Hosts mount iframes with sandbox="allow-scripts allow-forms allow-popups allow-same-origin". No access to the parent DOM, no access to the parent’s cookies — only the postMessage channel.
Anything posted from the iframe is in the user’s browser. Always re-validate on your backend before persisting.

See Also