React Components
@launchmystore/app-bridge-react ships two kinds of components:
- Chrome wrappers —
<TitleBar />,<NavigationMenu />,<Loading />. These render nothing visible. They render to the host chrome by calling the matching App Bridge action under the hood. - In-iframe UI primitives —
<AdminBlock>,<AdminAction>,<AdminPrintAction>, layout/text/form primitives. These render inside your extension iframe and give you a consistent look without pulling in a separate design system.
<AppBridgeProvider> ancestor — see
React Hooks.
Chrome wrappers
These are declarative shells around their matching hooks. They returnnull and re-render the host chrome whenever their props change. Use
them when you’d rather think in JSX than in imperative .update()
calls.
<TitleBar />
Sets the admin page title, primary/secondary action buttons, and
breadcrumbs. Wraps useTitleBar.
TitleBarProps)
| Prop | Type | Description |
|---|---|---|
title | string | Required. Shown as the page title in the host admin chrome. |
primaryAction | { label, onAction?, disabled?, loading?, destructive? } | Right-aligned filled button. |
secondaryActions | Array<{ label, onAction?, disabled?, destructive? }> | Plain buttons left of the primary. |
breadcrumbs | Array<{ label, url? | destination? }> | Rendered as a chevron-separated trail before the title. |
update() on the underlying action — flip
loading: true on the primary action to show a spinner without
re-creating the bar.
<NavigationMenu />
Registers a left-rail navigation menu for the app’s admin pages. Wraps
useNavigationMenu.
NavigationMenuProps)
| Prop | Type | Description |
|---|---|---|
items | Array<{ label, url, disabled?, icon?, badge? }> | Required. Order = render order. |
active | string | URL of the currently-active item — host highlights it. |
onNavigate | (url: string) => void | Called when the user clicks an item. Use this to push to your router. |
router.push(url)).
<Loading />
Toggles the global loading bar in the host chrome (the thin progress
strip at the top of the admin). Wraps
useLoading.
LoadingProps)
| Prop | Type | Default | Description |
|---|---|---|---|
loading | boolean | true | When true, the host loading bar is shown. The bar hides on unmount automatically. |
Contextual save bar
There’s no<ContextualSaveBar /> component — the save bar’s
imperative API (setSaveLoading, setDiscardLoading) is a poor fit
for declarative JSX. Use the
useContextualSaveBar
or useDirtyState
hooks instead:
Admin extension containers
Use these as the outermost element of any extension iframe. They give you a card / modal / print layout that matches the host admin look without you having to import a design system.<AdminBlock>
Outer container for block extension targets (product.details.block,
order.details.block, etc.). Renders a white card with a title and
padding.
AdminBlockProps) — title?: string, padding?: number (default 16), plus any HTMLDivElement attributes.
<AdminAction>
Container for modal-style action extension targets
(admin.order-details.action.render, etc.). Renders a scrolling body
with a sticky footer containing the primary + secondary action
buttons. The footer handles button states (loading / destructive /
disabled) for you.
AdminActionProps)
primaryAction?: { content, onAction?, loading?, destructive?, disabled? }secondaryActions?: Array<{ content, onAction?, disabled? }>- Plus any
HTMLDivElementattributes.
<AdminPrintAction>
Container for print extension targets
(admin.order-details.print.render). Renders a full-page print
layout with @media print rules that reset margins and colors. Use
usePrintReady() from inside the tree to signal the host that the
content has finished loading and can be sent to the printer.
data-print-ready="true" on the container and only
then calls the browser print dialog.
Layout primitives
Token-driven flex layouts. Gaps use the spacing scale"0" | "100" | "200" | "300" | "400" | "500" (= 0 | 4 | 8 | 12 | 16 | 24 px).
| Component | Purpose |
|---|---|
<BlockStack> | Vertical flex column. gap defaults to "200". |
<InlineStack> | Horizontal flex row. gap, align, blockAlign. |
<Box> | Generic <div> with token padding / background. |
<Divider> | Thin horizontal rule using tokens.color.border. |
Typography
| Component | Purpose |
|---|---|
<Text> | Body / heading text. variant (bodyXs–bodyLg, headingSm–headingXl), tone (base, subdued, critical, success, caution), fontWeight, as. |
<Heading> | h1–h6 with level: 1-6. Wraps <Text> with sensible defaults. |
<Link> | Anchor with token color + hover underline. Pass external for target="_blank" rel="noreferrer". |
Display
| Component | Purpose |
|---|---|
<Banner> | Tone-coloured callout. tone: 'info' | 'warning' | 'critical' | 'success', title, onDismiss. |
<Badge> | Pill label. tone (info, success, warning, critical, attention, new), size: 'small' | 'medium'. |
<Image> | <img> with rounded corners + lazy-loading default. |
<Icon> | Inline SVG icon. Pass a source SVG path or use the small built-in set. |
<EmptyState> | Centered “nothing here yet” block with optional <Button> action. |
<ProgressIndicator> | Determinate progress bar. value: 0-100. |
<Spinner> | Indeterminate circular spinner. size: 'small' | 'large'. |
Form
Controlled inputs. All callonChange(value) with the next value
(no event object). All accept label, helpText, error.
| Component | Purpose |
|---|---|
<TextField> | <input> / <textarea> (multiline). Supports prefix / suffix slots, type: 'text' | 'email' | 'password' | 'search' | 'tel' | 'url' | 'number'. |
<NumberField> | TextField with inputMode="numeric" + numeric onChange. min, max, step. |
<MoneyField> | TextField with currency prefix. currency: 'USD' (etc.). |
<DateField> | <input type="date"> returning ISO YYYY-MM-DD. |
<Select> | Native <select>. options: Array<{ label, value }>. |
<Checkbox> | Single boolean. |
<ChoiceList> | Radio (single) or checkbox (allowMultiple) group. choices: Array<{ label, value, helpText? }>. |
<Button> | variant: 'primary' | 'secondary' | 'tertiary' | 'plain', tone: 'base' | 'critical' | 'success', size, loading. |
<Form> | <form> that calls onSubmit(e) and prevents default. Useful for Enter to submit. |
Design tokens
All components read from a shared token set exported by@launchmystore/app-bridge-react:
tokens.color.*— base, surface, border, primary, critical, success, info, warning, plus*Subdued/*Bordervariants for banners.tokens.font.*—family,size.{xs,sm,md,lg,xl},weight.*,lineHeight.*.tokens.radius.*—sm(4),md(6),lg(8).tokens.shadow.*—smfor cards.
style prop — the
token style is spread first, your style last.
When to use components vs. hooks
| Goal | Use |
|---|---|
| Set the title bar declaratively | <TitleBar /> |
Toggle the title bar’s primaryAction.loading | Either — the component re-renders. |
| Open a confirmation modal once on click | useConfirmationModal hook |
| Render a scrolling-with-sticky-footer action page | <AdminAction> |
| Show / hide the host loading bar | <Loading loading={...} /> |
| Manage a contextual save bar tied to form state | useDirtyState hook |
| Open a resource picker imperatively | useResourcePicker / useApi().picker |
See Also
- React Hooks — every hook the components wrap, plus the data-fetching / cart / lifecycle hooks that have no component equivalent.
- Actions Reference — raw payload shapes for every App Bridge action.
- App Bridge Overview — the iframe ↔ host postMessage contract underneath all of this.