v0.5

Badge

Compact label for statuses, counts, and metadata.

NewVerifiedPendingDown12

Description

Badge is a small, non-interactive label used to tag content with a status, count, or category. It is a single-element component rendered as a <span> by default, with optional leading and trailing icons.

Reach for it when you need to surface a piece of metadata next to other content, such as an item state next to a row, a count on a navigation item, a tag in a list, or a category on a card. The visual weight is intentionally low so it complements the content it sits beside instead of competing with it.

Don't use Badge when the user needs to interact with it. If it triggers an action, use Button. If it represents an inline call-to-attention with title and body copy, use Alert. If it's a colored dot indicating presence (online / offline / away), use Status Badge. Reserve Badge for passive labels.

Installation

pnpm dlx @create-ui/cli add badge

Usage

import { Badge } from "@/components/ui/badge"
<Badge>New</Badge>

Examples

Variants

variant sets the semantic color. Twelve options cover product intents (primary), neutral metadata, status tones (success, danger, warning, info), and specialty tones (verified, highlighted, away, inverse).

PrimaryNeutralSuccessErrorWarningInfoVerifiedHighlightedAwayInverseNeutral StaticInverse Static

Appearance

appearance controls fill weight. soft is the default and works well in dense lists. solid is high-contrast for emphasis, outline is quiet, and ghost strips the background entirely.

SolidOutlineSoftGhost
SolidOutlineSoftGhost
SolidOutlineSoftGhost
SolidOutlineSoftGhost

Sizes

Three sizes (xs, sm, md) match the surrounding type scale. sm is the default.

xssmmd

Shape

shape="pill" makes the badge fully rounded; rounded (default) follows the size's radius scale.

RoundedPill

With Icon

Use leadingIcon and trailingIcon to render an icon inline. The component handles spacing and sizing per the active size.

LeadingTrailingBoth

Icon Only

iconOnly removes horizontal padding and forces a square footprint. Always pair with an aria-label so screen readers can announce the meaning.

Number Only

numberOnly is the count style: square-ish, centered, and designed for notification numerals (1, 12, 99) on navigation items or avatars.

11299

Accessibility

Badge is a passive label. By default it renders as a <span> and is not focusable; there are no keyboard interactions to document. If you render it as a link or button via the asChild prop, focus and keyboard behavior come from that underlying element.

KeyDescription
-Not focusable by default.

ARIA notes:

  • The component sets no implicit role; treat purely-decorative badges as such (e.g. add aria-hidden="true").
  • For badges that carry meaning beyond their visible label (e.g. an unread count), make sure the surrounding context exposes that meaning, either through the badge's text content or with aria-label on the parent control.
  • When using iconOnly, always provide an aria-label because the visual icon alone is not announced.

Styling

Tailwind override: pass className to merge Tailwind classes with the component's CVA classes (via cn()):

<Badge className="tracking-wide uppercase">Beta</Badge>

Data slots and attributes: the component sets these for CSS targeting:

  • data-slot="badge" on the root element.
  • data-slot="badge-icon" on each icon wrapper (leading and trailing).
  • data-slot="badge-label" on the inner text wrapper.
  • data-variant="<variant>", data-appearance="<appearance>", data-size="<size>" on the root.

Target a specific state in CSS:

[data-slot="badge"][data-variant="danger"] {
  /* … */
}
  • Status Badge: colored dot + label for presence states (online, offline, away).
  • App Store Badge: branded download CTA for App Store / Play Store.
  • Button: use this when the element needs to be interactive.
  • Alert: use this for full callouts with title and description, not inline labels.

API Reference

Badge

Passive label for tagging content with a status, count, or category. Extends React.ComponentProps<"span">, so any standard span attribute (id, role, aria-*, onClick, etc.) is accepted.

Props

PropTypeDefaultDescription
asChildbooleanfalseRender as the child element via Radix Slot. Use to make the badge act as a link.
leadingIconReact.ReactNode-Icon rendered before the label. Ignored when iconOnly or numberOnly is true.
trailingIconReact.ReactNode-Icon rendered after the label. Ignored when iconOnly or numberOnly is true.
iconOnlybooleanfalseSquare footprint with no horizontal padding; renders children as the only content.
numberOnlybooleanfalseCount-style footprint (centered, min-width per size) for short numerals.
classNamestring-Tailwind classes merged with the component's CVA classes via cn().
childrenReact.ReactNode-Badge content. Text for default mode, an icon for iconOnly, a numeral for numberOnly.

Variants

VariantOptionsDefaultDescription
variant"primary" "neutral" "danger" "success" "warning" "info" "verified" "highlighted" "away" "inverse""primary"Semantic color intent.
appearance"solid" "outline" "soft" "ghost""soft"Fill weight. solid for emphasis, ghost for no surface.
size"xs" "sm" "md""sm"Size scale; controls height, padding, type, and icon size.
shape"rounded" "pill""rounded"pill is fully rounded; rounded follows the size scale.