Persona

Badge

Data display · 2 props · Updated Sep 22, 2026

A badge is a small colored dot holding a count. variant and onSecondaryBackground are the whole API: there is no label, icon, dismiss or size prop, and the count is the only thing a badge can say.

  • 3
    3
    Container the dot itself, colored by variant, and 16px wide before the count widens it.
  • 3
    3
    Count a number inside the dot, for how many things are waiting. It is required: with no count, the component renders nothing.

Badge is a Sticker underneath — the same component with a round corner radius, a 16px minimum width and 10px text. It inherits Sticker’s one requirement: a sticker with neither children nor an icon logs a warning and returns null.

So <Badge variant="alert" /> renders nothing at all: server-rendered, an empty badge produces an empty parent element and a console warning. The unread dot with no number is a real pattern and this component is not it. Until Badge can render without children, a dot on its own is markup of yours, not a badge.

Use a badge to mark that something has arrived and not been opened yet: unread messages, new results in a tab, items waiting in a queue. The badge marks the thing; the thing it marks is what you click.

If the state needs a word — “Active”, “Pending”, “Beta” — use a Sticker, whose text is what carries its meaning. For a message the reader has to act on, use a Banner. For an explanation, use a Tooltip or plain inline text.

A badge carries no words and occupies 16px, so the whole of its signal is that it is the one colored thing in an otherwise quiet view. Put four on a screen and the reader has to compare them to find out which one matters, which is work the badge existed to save. Where several things are counted at once, the counts belong in the content — a column, a list, a heading — rather than in four dots.

variant is basic, active or alert — grey, purple and red, defaulting to basic. The names describe color and nothing else: none of them is text the badge displays, and none of them changes what the count means.

Grey counts something; purple says this is the active or selected one; red says the count is a problem. onSecondaryBackground adjusts the fill for a tinted surface, such as inside a panel or a card with a grey background.

The count reaches a screen reader as a bare number

Section titled “The count reaches a screen reader as a bare number”

Color is the badge’s only channel, so “3” has to be understandable from somewhere else. Two places will do it: the labeled thing the badge sits next to, or an aria-label on the badge itself — Badge passes its remaining props through to the rendered element, so aria-label lands where it needs to.

Nothing announces a change. The count updates silently, and a reader who has already passed it will not hear that it moved.

Nothing in the component caps it. The count renders at 10px inside a 16px pill and never wraps, so a four-digit number either widens the dot into a stripe or, where its container caps the width, truncates to an ellipsis — “120…” is a worse answer than no number. Send “99+” rather than 1,204; past two digits the exact figure has stopped being what the reader wanted from a dot.

NameType
onSecondaryBackground

boolean

When rendered on a secondary background (e.g. inside a panel or card with a grey fill), set this to true so the component adjusts its colours appropriately for certain variants.

variant

alert, active, basic

Semantic colour variant for the badge.

  • basic – neutral grey, for informational counts or labels (default).
  • active – purple, to highlight an active or selected state.
  • alert – red/danger, to draw attention to errors or urgent counts.

Was this page helpful?