Skip to main content
Migrate to Polaris

Version 2025-07 is the last API version to support React-based UI components. Later versions use web components, native UI elements with built-in accessibility, better performance, and consistent styling with Shopify's design system. Check out the migration guide to upgrade your extension.

Banner

The Banner component displays a prominent message to merchants with an optional title, tone, dismiss button, and action buttons. Use it for important information, warnings, errors, or success confirmations that require merchant attention.

For small inline status labels, use Badge.

Support
Targets (46)

Supported targets


Props for the Banner component, which displays a prominent message to the merchant. Banners communicate important information, status updates, warnings, or errors, with optional primary and secondary actions.

Anchor to dismissible
dismissible
boolean
Default: false

Whether the banner can be dismissed by the merchant. When true, then a close button is rendered that allows the merchant to hide the banner.

string

A unique identifier for the element.

Anchor to onDismiss
onDismiss
() => void

A callback fired when the merchant dismisses the banner by pressing the close button. Use this to update your state and stop rendering the banner. Only relevant when dismissible is true.

Anchor to primaryAction
primaryAction
RemoteFragment

The primary action for the banner, rendered as a Button. Use this for the main action related to the banner message, such as "Review" or "Fix issue".

Anchor to secondaryAction
secondaryAction
RemoteFragment

The secondary action for the banner, rendered as a Button. Use this for an alternative or less prominent action, such as "Learn more" or "Dismiss".

Anchor to title
title
string

The main message displayed inside the banner. Use this to communicate important information, status updates, or actionable messages to the merchant.

The color and icon of the banner, conveying its semantic meaning.


Anchor to Warn about API sync failureWarn about API sync failure

Show a product sync failure with a retry action. This example renders a dismissible Banner with a critical tone, a primary action Button that retries the sync, and a message explaining the issue.

Warn about API sync failure

Show a product sync failure with a retry action. This example renders a dismissible `Banner` with a `critical` tone, a primary action [Button](/docs/api/admin-extensions/2025-07/ui-components/actions/button) that retries the sync, and a message explaining the issue.

Warn about API sync failure

import {useState} from 'react';
import {reactExtension, useApi, Banner, Button, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data} = useApi('admin.product-details.block.render');
const productId = data.selected[0]?.id;
const [visible, setVisible] = useState(true);

if (!visible) return null;

return (
<BlockStack>
<Banner
title="Product sync failed"
tone="critical"
dismissible
onDismiss={() => setVisible(false)}
primaryAction={
<Button
onPress={async () => {
await fetch('/api/products/sync', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId}),
});
}}
>
Retry sync
</Button>
}
>
The last sync attempt could not reach your warehouse system. Check your
API credentials and try again.
</Banner>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
import {extension, Banner, Button, BlockStack} from '@shopify/ui-extensions/admin';

export default extension(
'admin.product-details.block.render',
(root, api) => {
const {data} = api;
const productId = data.selected[0]?.id;

const stack = root.createComponent(BlockStack);

const retryButton = root.createComponent(
Button,
{
onPress: async () => {
await fetch('/api/products/sync', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId}),
});
},
},
'Retry sync',
);

const banner = root.createComponent(
Banner,
{
title: 'Product sync failed',
tone: 'critical',
dismissible: true,
onDismiss: () => {
stack.removeChild(banner);
},
primaryAction: retryButton,
},
'The last sync attempt could not reach your warehouse system. Check your API credentials and try again.',
);

stack.appendChild(banner);
root.appendChild(stack);
},
);

Anchor to Confirm successful product updateConfirm successful product update

Show a success banner after completing a product update to give merchants immediate visual confirmation. This example renders a dismissible banner with a message that includes the product ID, so merchants know exactly which resource was updated.

Confirm successful product update

import {useState} from 'react';
import {reactExtension, useApi, Banner, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data} = useApi('admin.product-details.block.render');
const productId = data.selected[0]?.id;
const [visible, setVisible] = useState(true);

if (!visible) return null;

return (
<BlockStack>
<Banner
title="Product updated successfully"
tone="success"
dismissible
onDismiss={() => setVisible(false)}
>
Tags and metafields for product {productId} have been synced to your
external catalog.
</Banner>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
import {extension, Banner, BlockStack} from '@shopify/ui-extensions/admin';

export default extension(
'admin.product-details.block.render',
(root, api) => {
const {data} = api;
const productId = data.selected[0]?.id;

const stack = root.createComponent(BlockStack);

const banner = root.createComponent(
Banner,
{
title: 'Product updated successfully',
tone: 'success',
dismissible: true,
onDismiss: () => {
stack.removeChild(banner);
},
},
`Tags and metafields for product ${productId} have been synced to your external catalog.`,
);

stack.appendChild(banner);
root.appendChild(stack);
},
);

Anchor to Display form validation warningsDisplay form validation warnings

Show warning validation issues at the top of an action modal before merchants submit. This example combines a banner with secondaryAction to let merchants review or dismiss the warning before proceeding.

Display form validation warnings

import {reactExtension, useApi, Banner, Button, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {close} = useApi('admin.product-details.action.render');

return (
<BlockStack>
<Banner
title="Missing required fields"
tone="warning"
secondaryAction={
<Button onPress={() => close()}>Dismiss</Button>
}
>
The product is missing a weight and shipping dimensions. These fields
are required by your fulfillment provider before orders can be
processed.
</Banner>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
import {extension, Banner, Button, BlockStack} from '@shopify/ui-extensions/admin';

export default extension(
'admin.product-details.action.render',
(root, api) => {
const {close} = api;

const stack = root.createComponent(BlockStack);

const dismissButton = root.createComponent(
Button,
{onPress: () => close()},
'Dismiss',
);

const banner = root.createComponent(
Banner,
{
title: 'Missing required fields',
tone: 'warning',
secondaryAction: dismissButton,
},
'The product is missing a weight and shipping dimensions. These fields are required by your fulfillment provider before orders can be processed.',
);

stack.appendChild(banner);
root.appendChild(stack);
},
);

  • Focus on a single message: Present one piece of information or required action per banner to maintain clarity. If you have multiple messages, stack separate banners.
  • Keep messages concise: Write content that merchants can quickly scan and understand without spending time deciphering the meaning or next steps.
  • Provide clear actions: For warning and critical banners, include a primaryAction or secondaryAction with specific next steps so merchants know how to proceed.
  • Use tones consistently: Use one tone consistently for the same status across your extension, such as info for general information. Don't mix warning and critical for the same severity level — merchants will lose trust in the signal if tones are inconsistent.

  • The dismissed state doesn't persist across page loads or sessions. You must implement your own persistence logic using app storage or server-side state if you want a banner to stay dismissed.
  • Multiple banners stack vertically without built-in prioritization or queueing. If you show several banners at once, they all appear simultaneously. Implement your own queueing logic if you need to show one at a time.
  • Banner supports only plain text strings, Text components, and Link components as content. For complex layouts with multiple elements, use a Section component instead.

Was this page helpful?