Skip to main content

Badge

A non-interactive label used to highlight short, scannable information — a status, a category tag, or a count — in the smallest possible footprint.

When to use

  • Status indicators: Succeeded, Failed, Pending, Beta.
  • Category or tag chips alongside list items, table rows, or cards.
  • Counts (e.g. 12 new) when paired with brief context.

When not to use

  • For interactive UI. Badges are not buttons or links; use Button or Anchor (optionally with asChild styling) instead.
  • For long-form text. Keep labels to one or two short words.
  • As the sole signal of meaning. Pair color with a label or icon so the distinction works without color (color blindness, monochrome themes).

Choosing a color

Prefer functional colors (success, warning, danger, info, accent, neutral) for status meaning so theming stays coherent. Reach for named hues only when the badge's semantic role isn't already covered.

  • Muted amberMuted amber
  • Muted blueMuted blue
  • Muted cyanMuted cyan
  • Muted emeraldMuted emerald
  • Muted fuchsiaMuted fuchsia
  • Muted grayMuted gray
  • Muted greenMuted green
  • Muted indigoMuted indigo
  • Muted limeMuted lime
  • Muted orangeMuted orange
  • Muted pinkMuted pink
  • Muted purpleMuted purple
  • Muted redMuted red
  • Muted roseMuted rose
  • Muted skyMuted sky
  • Muted tealMuted teal
  • Muted violetMuted violet
  • Muted yellowMuted yellow
  • Muted importantMuted important
  • Muted infoMuted info
  • Muted accentMuted accent
  • Muted dangerMuted danger
  • Muted neutralMuted neutral
  • Muted successMuted success
  • Muted warningMuted warning
import { Badge } from "@ngrok/mantle/badge";import { GlobeHemisphereWestIcon } from "@phosphor-icons/react/GlobeHemisphereWest"; <Badge appearance="muted" color="neutral">	Muted neutral</Badge><Badge appearance="muted" color="neutral" icon={<GlobeHemisphereWestIcon />}>	Muted neutral</Badge>

Polymorphism

When you want to render something else as a Badge, you can use the asChild prop to compose. This is useful when you want to splat the Badge styling onto a react-router Link.

import { Badge } from "@ngrok/mantle/badge";import { GlobeHemisphereWestIcon } from "@phosphor-icons/react/GlobeHemisphereWest";import { Link, href } from "react-router"; <Badge appearance="muted" asChild color="pink" icon={<GlobeHemisphereWestIcon />}>	<Link to={href("/base/colors")}>See our colors!</Link></Badge>;

API Reference

Badge

All props from span, plus:

PropTypeDefaultDescription
appearance"muted"Defines the visual style of the Badge. Currently only supports the muted variant.
asChild?booleanfalseUse the asChild prop to compose the Badge styling onto alternative element types or your own React components.
color?"accent" | "danger" | "important" | "info" | "neutral" | "success" | "warning" | "amber" | "blue" | "cyan" | "emerald" | "fuchsia" | "gray" | "green" | "indigo" | "lime" | "orange" | "pink" | "purple" | "red" | "rose" | "sky" | "teal" | "violet" | "yellow""neutral"The color variant of the Badge. Supports every named color, functional and palette.
icon?ReactNodeAn icon to render inside the badge. Sized to the badge. Decorative by default: it renders aria-hidden unless the SVG carries aria-label, aria-labelledby, role, or an explicit aria-hidden.

Data attributes

Data AttributeValueDescription
data-slot"badge"On the badge element. Stable styling hook that survives a className override or an asChild swap.
data-slot"badge-label"On the <span> wrapping children, beside the icon slot. display: contents, so every child stays a flex item of the badge and the gap still falls between them. Style a label by styling your own child, not this slot.