UI primitives let your app place a small set of controls in the surrounding Storeadmin interface. Use them for actions and status that belong to the current app screen. Your app still owns the content inside its embedded page. On iOS and Android, the supported primitives are toast, loading, and setting the title bar. Other controls described here require the web admin. After bridge.ready(), check bridge.supports(operation) before showing an action that depends on optional host UI.
Primitives cover controls in Storeadmin's chrome. To make the content inside your own page look native, use the App Bridge UI kit.
Show brief feedback#
Use bridge.toast(message, variant?) after a short action such as saving, copying, or completing a step. message is required and accepts up to 500 characters. variant can be "default", "success", or "error"; it defaults to "default".
await bridge.toast("Campaign saved", "success");
Show ongoing work#
Call bridge.loading.start() while the current app view is waiting for work to finish, then call bridge.loading.stop(). Repeating either call is safe.
bridge.loading.start();
try {
await refreshCampaigns();
} finally {
await bridge.loading.stop();
}
Keep important status visible#
bridge.banner.show(options) displays a notice above the app until your app hides it or the merchant dismisses it. Use a banner for setup requirements, service interruptions, or another status that should remain visible. Supported tones are also available as bridge.banner.TONES.
Field |
Required |
Default |
Limit or values |
|---|---|---|---|
message |
yes |
— |
1–1000 characters |
tone |
no |
|
|
title |
no |
empty |
Up to 120 characters |
dismissible |
no |
|
Boolean |
action |
no |
none |
|
The action emits banner:action with its id. Dismissing the banner emits banner:dismiss. Call bridge.banner.hide() when the status no longer applies.
await bridge.banner.show({
title: "Connection needed",
message: "Reconnect your account to resume syncing.",
tone: "warning",
action: { id: "reconnect", content: "Reconnect" },
});
bridge.on("banner:action", ({ id }) => {
if (id === "reconnect") openConnection();
});
Protect unsaved work#
Call bridge.saveBar.show(options?) when a form becomes dirty and bridge.saveBar.hide() after a successful save or discard. Save emits savebar:save; Discard emits savebar:discard.
Field |
Default |
Limit or meaning |
|---|---|---|
message |
|
Up to 200 characters |
saveLabel |
|
Up to 40 characters |
discardLabel |
|
Up to 40 characters |
saveDisabled |
|
Disables Save |
loading |
|
Shows Save in progress |
await bridge.saveBar.show({
message: "Campaign has unpublished changes",
saveLabel: "Publish",
});
bridge.on("savebar:save", async () => {
await bridge.saveBar.show({ loading: true });
await publishCampaign();
await bridge.saveBar.hide();
});
Set the page title and actions#
bridge.titleBar.set(options) sets the title and optional actions for the current app screen. title is required and accepts up to 120 characters. Each action needs an id and content; up to three secondary actions are supported. Action clicks emit titlebar:action. Call bridge.titleBar.clear() to restore the default app header.
await bridge.titleBar.set({
title: "Campaigns",
primaryAction: { id: "new", content: "New campaign" },
});
bridge.on("titlebar:action", ({ id }) => {
if (id === "new") createCampaign();
});
Add app navigation#
bridge.nav.set({ items }) adds your app sections beneath the app in the Storeadmin sidebar. Provide 1–10 items. Every item needs an id and label; set current: true on the active item. A selection emits nav:navigate with the item id. Your app remains responsible for changing its own route and content. Call bridge.nav.clear() when the menu no longer applies.
await bridge.nav.set({
items: [
{ id: "overview", label: "Overview", current: true },
{ id: "settings", label: "Settings" },
],
});
bridge.on("nav:navigate", ({ id }) => {
appRouter.open(id);
});
Use the full workspace#
bridge.fullscreen.enter() expands the embedded app to the available viewport. bridge.fullscreen.exit() returns to the standard Storeadmin layout. The host keeps an Exit fullscreen control available and emits fullscreen:change whenever the state changes.