Banner
Banner draws a notice: a tinted wash fading from the left, a boxed icon in the tone, a title and a line of explanation, link buttons on the right (the last one is the main action) and an optional close button. size: "sm" is the compact one-line banner for cards and side panels.
BannerUsage
import { Banner } from "@antelopejs/interface-dms/base/banner";
static beta = Banner({
tone: "warning",
title: "$shop.sales.beta_title",
description: "$shop.sales.beta_description",
actions: [{ label: "$shop.sales.feedback", to: "#feedback" }],
dismissible: true,
dismissKey: "sales-beta-2026",
});
Options
| Option | Type | Default | Description |
|---|---|---|---|
titleContent | string | object | – | |
descriptionContent | string | object | – | |
toneAppearance | "info" | "success" | "warning" | "error" | "primary" | "info" | The colour of the banner and of its icon. |
iconAppearance | string | – | Replaces the icon the tone comes with. |
sizeAppearance | "md" | "sm" | "md" | Compact keeps the banner to one line. |
dismissibleBehavior | boolean | – | Adds a close button; once closed, the banner stays hidden for that person. |
Recipes
Let the backend decide
When the backend decides whether there is something to say — a computed health status, a provider outage — set fetchUrl. The route answers a BannerContent (any of title, description, tone, icon, size, actions, dismissible, dismissKey, each overriding the static option), or null, {} or a 204 for no banner: the block then draws nothing and takes no space. Nothing is drawn while the first answer loads either.
Actions a route answers may also run a target, as in a page header: { label, icon?, variant?, color?, target, confirm? } with an api call, a modal, a drawer, a quickAction, a link or an export. One that changed something refreshes the page's blocks, so the banner reads its route again and goes away once the route answers null.
static providerStatus = Banner({ fetchUrl: "/api/mailing/{{params.id}}/provider-status" });
@Get(":id/provider-status")
providerStatus(): BannerContent | null {
if (!isProviderDown()) return null;
return {
tone: "error",
title: "$mailing.outage.title",
description: { key: "mailing.outage.queued", params: { count: { type: "count", value: 1284 } } },
actions: [{
label: "$mailing.outage.replay",
target: { type: "api", method: "POST", url: "/api/mailing/replay", successMessage: "$mailing.outage.replayed" },
confirm: { title: "$mailing.outage.replay_confirm" },
}],
};
}
Show it again
A dismissed banner stays dismissed for a year, in a cookie, so the server render already leaves it out. It is remembered under dismissKey, or the block's id on its page without one. Change the key to show the banner again (a new beta, a new notice).
Pitfalls
- A
Banneris placed on one page. For a strip under the dashboard header on every page, useRegisterLayoutBanner(Dashboard chrome). - Static
actionsare links only; buttons that run a target come from the route.

