[data-reveal]{opacity:1!important;transform:none!important}
Banner
Components

Banner

A notice with a tone, link buttons and a remembered dismiss — static, or fetched from a route that decides whether to show it.

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.

BannerBanner
Connecting to the DMS preview…
ConnectingDMS 0.9.56 options set

Usage

src/pages/sales.ts
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

Options of the Banner block
OptionTypeDefaultDescription
titleContentstring | object–
descriptionContentstring | object–
toneAppearance"info" | "success" | "warning" | "error" | "primary""info"The colour of the banner and of its icon.
iconAppearancestring–Replaces the icon the tone comes with.
sizeAppearance"md" | "sm""md"Compact keeps the banner to one line.
dismissibleBehaviorboolean–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.

src/pages/mailing.ts
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 Banner is placed on one page. For a strip under the dashboard header on every page, use RegisterLayoutBanner (Dashboard chrome).
  • Static actions are links only; buttons that run a target come from the route.

Next steps

Layout banners

A banner on every page.

Empty state

When the notice replaces the content.