These are host-drawn dialogs rendered outside your iframe, so the merchant can trust it is really Tringify asking. For the picker and editor, the host also fetches the content itself — on the merchant's own Tringify Storeadmin session, not your app's Store API token. Your app supplies only which resource or template; the rows are exactly what that merchant is allowed to see, and your app can neither supply them nor filter them. The reply arrives when the merchant acts; these calls wait indefinitely (no timeout) because a human reading a dialog outlasts any fixed one.
bridge.modal.open(options)#
A host-drawn modal. title is required (throws if empty). body is optional text (rendered as plain text, no HTML). primaryAction is optional { content, destructive? }; secondaryAction is optional { content } — a given action with empty content throws. Resolves { action: "primary" | "secondary" | "dismiss" }.
const { action } = await bridge.modal.open({
title: "Publish campaign?",
body: "It will start sending immediately.",
primaryAction: { content: "Publish" },
secondaryAction: { content: "Cancel" },
});
if (action === "primary") publish();
bridge.modal.confirm(options)#
A convenience confirm. title is required; confirmText (default Confirm), cancelText (default Cancel), body, and destructive are optional. Resolves true if the merchant confirmed, false for cancel or dismiss.
if (await bridge.modal.confirm({ title: "Delete this list?", destructive: true })) {
await deleteList();
}
bridge.resourcePicker.open(options)#
Opens a host resource picker. Tringify Storeadmin fetches the rows on the merchant's own admin session and renders them; you get back only the selection. Your app never sees the full list and cannot influence which rows appear.
Field |
Required |
Default |
Meaning |
|---|---|---|---|
resource |
yes |
— |
Which resource to pick. Must be a supported resource (see below) or the call throws. |
selectionMode |
no |
|
|
query |
no |
— |
An initial search string. |
initialSelectionIds |
no |
— |
Array of ids to pre-select (coerced to strings). |
Resolves { selection: [{ id, title, subtitle? }] } — selection is [] if the merchant cancels. The supported resources are exposed at runtime on bridge.resourcePicker.RESOURCES; passing a resource not in that list throws immediately (a loud programming error, not an empty dialog).
const { selection } = await bridge.resourcePicker.open({
resource: "tag",
selectionMode: "multiple",
});
// selection: [{ id, title }]
bridge.templateEditor.open(options)#
Opens a host template editor: the host loads the template through Tringify, the merchant edits and saves it, and you get back the result. Both kind and type are required. kind must be a supported kind (see bridge.templateEditor.KINDS) or the call throws; type is the specific template type (for example login_otp).
Resolves { saved: boolean, template? } — saved is false if the merchant cancels. Editing is gated by your app's granted scopes intersected with the merchant's permissions (read to open, write to save) — the host editor cannot touch a template your own session token could not.
const { saved } = await bridge.templateEditor.open({ kind: "sms", type: "login_otp" });
if (saved) refresh();