Badge
A compact label for status, counts and metadata, with tinted status variants, a status dot and an AI variant.
npx prodular-ui add badgeVariants
Neutral variants for metadata. Tinted status variants for state.
PaidScheduledPast dueFailed
import { Badge } from "@/components/ui/badge"
export default function BadgeVariants() { return ( <div className="flex flex-col items-center gap-4"> <div className="flex flex-wrap items-center justify-center gap-2"> <Badge>Enterprise</Badge> <Badge variant="secondary">Draft</Badge> <Badge variant="outline">v2.14.0</Badge> <Badge variant="ghost">Archived</Badge> <Badge variant="link" render={<a href="#changelog" />}> Changelog </Badge> </div> <div className="flex flex-wrap items-center justify-center gap-2"> <Badge variant="success">Paid</Badge> <Badge variant="info">Scheduled</Badge> <Badge variant="warning">Past due</Badge> <Badge variant="destructive">Failed</Badge> </div> </div> )}Status dot
BadgeDot takes the badge color. In a neutral badge, pass status to color only the dot.
OperationalDegradedOutageMaintenance
LivePending reviewPaused
import { Badge, BadgeDot } from "@/components/ui/badge"
export default function BadgeDotDemo() { return ( <div className="flex flex-col items-center gap-4"> <div className="flex flex-wrap items-center justify-center gap-2"> <Badge variant="success"> <BadgeDot /> Operational </Badge> <Badge variant="warning"> <BadgeDot pulse /> Degraded </Badge> <Badge variant="destructive"> <BadgeDot /> Outage </Badge> <Badge variant="info"> <BadgeDot /> Maintenance </Badge> </div> <div className="flex flex-wrap items-center justify-center gap-2"> <Badge variant="outline"> <BadgeDot status="success" /> Live </Badge> <Badge variant="outline"> <BadgeDot status="warning" /> Pending review </Badge> <Badge variant="outline"> <BadgeDot status="neutral" /> Paused </Badge> </div> </div> )}AI
Marks content a model produced. Tinted with the AI hairline.
AI summarySuggestedDrafted
import { SparklesIcon } from "lucide-react"
import { Badge } from "@/components/ui/badge"
export default function BadgeAi() { return ( <div className="flex flex-wrap items-center justify-center gap-2"> <Badge variant="ai"> <SparklesIcon data-icon="inline-start" /> AI summary </Badge> <Badge variant="ai">Suggested</Badge> <Badge variant="ai" size="sm"> <SparklesIcon data-icon="inline-start" /> Drafted </Badge> </div> )}Sizes
sm for dense tables and inline text, default everywhere else.
12 openVerifiedSynced
12 openVerifiedSynced
import { CheckIcon } from "lucide-react"
import { Badge, BadgeDot } from "@/components/ui/badge"
export default function BadgeSizes() { return ( <div className="flex flex-col items-center gap-4"> <div className="flex flex-wrap items-center justify-center gap-2"> <Badge size="sm" variant="secondary"> 12 open </Badge> <Badge size="sm" variant="success"> <CheckIcon data-icon="inline-start" /> Verified </Badge> <Badge size="sm" variant="outline"> <BadgeDot status="success" /> Synced </Badge> </div> <div className="flex flex-wrap items-center justify-center gap-2"> <Badge variant="secondary">12 open</Badge> <Badge variant="success"> <CheckIcon data-icon="inline-start" /> Verified </Badge> <Badge variant="outline"> <BadgeDot status="success" /> Synced </Badge> </div> </div> )}Anatomy
<Badge variant="success"> <BadgeDot /> Operational</Badge>Guidance
Use it when
- Show the state of a record: Paid, Past due, Failed, Live.
- Show short metadata next to a title: a version, a plan, a count.
- Use the ai variant on content a model wrote or suggested, so people can tell it apart from their own.
Avoid
- Badges as buttons. If clicking it does something, use a Button or a Toggle.
- More than one or two badges per row in a table. Pick the one that matters.
- default (solid) badges for status. Solid fills are loud. Keep them for one highlighted label, such as a plan name.
Rules for AI agents
Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.
- Map status to variant consistently: success for completed or healthy, warning for needs attention, destructive for failed or blocked, info for scheduled or neutral system states.
- Use BadgeDot for live or ongoing states (Operational, Building). Add pulse only while the state is actively changing.
- Inside outline or secondary badges, set BadgeDot status to color the dot. Never color the badge text yourself.
- Use size="sm" inside table cells and next to 14px text. Use the default size next to headings.
- Keep badge text to one or two words in sentence case. No uppercase.
- Use the ai variant only for model output, never for features that merely mention AI.
API
Badge
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "secondary" | "outline" | "ghost" | "link" | "success" | "warning" | "info" | "destructive" | "ai" | "default" | Visual style. Status variants are tinted. |
| size | "sm" | "default" | "default" | Height: 20px or 24px. |
| render | ReactElement | Renders the badge as another element, for example a link. |
BadgeDot
| Prop | Type | Default | Description |
|---|---|---|---|
| status | "success" | "warning" | "info" | "destructive" | "ai" | "neutral" | Dot color. Defaults to the badge variant color. | |
| pulse | boolean | false | Adds a pulsing ring for live states. Hidden with reduced motion. |
Installation
The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.
npx prodular-ui add badge# or, with the registry in components.jsonnpx shadcn@latest add @prodular/badge