Badge
Highlight key statuses. Draw attention to critical metrics.
Acme Studio
ProRenews Apr 12, 7 of 10 seats used
1import { Badge } from '@/components/ui/badge';2import { Flex } from '@/components/ui/flex';3import { Stack } from '@/components/ui/stack';45export function Default() {6 return (7 <Stack gap="1" className="border-border bg-card w-full max-w-sm rounded-xl border p-4">8 <Flex align="center" gap="2">9 <p className="truncate text-sm font-medium">Acme Studio</p>10 <Badge>Pro</Badge>11 </Flex>12 <p className="text-muted-foreground text-xs">Renews Apr 12, 7 of 10 seats used</p>13 </Stack>14 );15}
Installation
Copy and paste the following code into your project.
1import { cva, type VariantProps } from 'class-variance-authority';2import * as React from 'react';3import { cn } from '../lib/cn';45const badgeVariants = cva(6 'inline-flex items-center justify-center gap-1 rounded-sm border px-2 py-0.5 text-[11px] font-medium tracking-wide whitespace-nowrap transition-colors [&>svg]:size-3 [&>svg]:shrink-0',7 {8 variants: {9 variant: {10 default: 'bg-primary text-primary-foreground border-primary/20',11 secondary: 'bg-secondary text-secondary-foreground border-secondary-foreground/10',12 destructive: 'bg-destructive-surface text-destructive-text border-destructive-border',13 success: 'bg-success-surface text-success-text border-success-border',14 warning: 'bg-warning-surface text-warning-text border-warning-border',15 info: 'bg-info-surface text-info-text border-info-border',16 outline: 'text-foreground border-border bg-transparent',17 },18 },19 defaultVariants: {20 variant: 'default',21 },22 },23);2425export interface BadgeProps26 extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {}2728const Badge = ({29 className,30 variant,31 ref,32 ...props33}: BadgeProps & { ref?: React.Ref<HTMLSpanElement> }) => {34 return <span ref={ref} className={cn(badgeVariants({ variant }), className)} {...props} />;35};3637Badge.displayName = 'Badge';3839export { Badge, badgeVariants };
Update the import paths to match your project structure.
Anatomy
1import { Badge } from '@/components/ui/badge';
1<Badge variant="outline">Badge</Badge>
Examples
Default
Acme Studio
ProRenews Apr 12, 7 of 10 seats used
1import { Badge } from '@/components/ui/badge';2import { Flex } from '@/components/ui/flex';3import { Stack } from '@/components/ui/stack';45export function Default() {6 return (7 <Stack gap="1" className="border-border bg-card w-full max-w-sm rounded-xl border p-4">8 <Flex align="center" gap="2">9 <p className="truncate text-sm font-medium">Acme Studio</p>10 <Badge>Pro</Badge>11 </Flex>12 <p className="text-muted-foreground text-xs">Renews Apr 12, 7 of 10 seats used</p>13 </Stack>14 );15}
Secondary
NB
OwnerNadia Brenner
nadia@acmestudio.dev
TO
AdminTomas Ovalle
tomas@acmestudio.dev
RK
ViewerRhea Kapoor
rhea@acmestudio.dev
1'use client';23import { Avatar } from '@/components/ui/avatar';4import { Badge } from '@/components/ui/badge';5import { Flex } from '@/components/ui/flex';6import { Stack } from '@/components/ui/stack';78const members = [9 { initials: 'NB', name: 'Nadia Brenner', email: 'nadia@acmestudio.dev', role: 'Owner' },10 { initials: 'TO', name: 'Tomas Ovalle', email: 'tomas@acmestudio.dev', role: 'Admin' },11 { initials: 'RK', name: 'Rhea Kapoor', email: 'rhea@acmestudio.dev', role: 'Viewer' },12];1314export function Secondary() {15 return (16 <Stack gap="4" className="border-border bg-card w-full max-w-md rounded-xl border p-4">17 {members.map((member) => (18 <Flex key={member.email} align="center" justify="between" gap="4">19 <Flex align="center" gap="3" className="min-w-0">20 <Avatar>21 <Avatar.Fallback>{member.initials}</Avatar.Fallback>22 </Avatar>23 <div className="min-w-0">24 <p className="truncate text-sm font-medium">{member.name}</p>25 <p className="text-muted-foreground truncate text-xs">{member.email}</p>26 </div>27 </Flex>28 <Badge variant="secondary">{member.role}</Badge>29 </Flex>30 ))}31 </Stack>32 );33}
Destructive
Bump checkout timeout
main · 8f2c1a4
Retry Stripe webhooks
fix/webhooks · 3ad9e07
1import { Badge } from '@/components/ui/badge';2import { Flex } from '@/components/ui/flex';3import { Stack } from '@/components/ui/stack';45const deploys = [6 { branch: 'main', commit: '8f2c1a4', message: 'Bump checkout timeout', status: 'Failed' },7 { branch: 'fix/webhooks', commit: '3ad9e07', message: 'Retry Stripe webhooks', status: 'Failed' },8];910export function Destructive() {11 return (12 <Stack gap="4" className="border-border bg-card w-full max-w-md rounded-xl border p-4">13 {deploys.map((deploy) => (14 <Flex key={deploy.commit} align="center" justify="between" gap="4">15 <div className="min-w-0">16 <p className="truncate text-sm font-medium">{deploy.message}</p>17 <p className="text-muted-foreground truncate font-mono text-xs">18 {deploy.branch} · {deploy.commit}19 </p>20 </div>21 <Badge variant="destructive">{deploy.status}</Badge>22 </Flex>23 ))}24 </Stack>25 );26}
Outline
checkout-api
Deployed Mar 14 at 09:41
v2.4.0node 22eu-central-1
1import { Badge } from '@/components/ui/badge';2import { Flex } from '@/components/ui/flex';3import { Stack } from '@/components/ui/stack';45const tags = ['v2.4.0', 'node 22', 'eu-central-1'];67export function Outline() {8 return (9 <Stack gap="3" className="border-border bg-card w-full max-w-sm rounded-xl border p-4">10 <div>11 <p className="text-sm font-medium">checkout-api</p>12 <p className="text-muted-foreground mt-1 text-xs">Deployed Mar 14 at 09:41</p>13 </div>14 <Flex wrap="wrap" gap="2">15 {tags.map((tag) => (16 <Badge key={tag} variant="outline">17 {tag}18 </Badge>19 ))}20 </Flex>21 </Stack>22 );23}
With Icon
Unit tests
412 passed in 38s
Type check
Running on node 22
Bundle size
+12kb over budget
1import { Badge } from '@/components/ui/badge';2import { AlertTriangleIcon } from '@/components/ui/alert-triangle';3import { CheckIcon } from '@/components/ui/check';4import { LoaderIcon } from '@/components/ui/loader';5import { Flex } from '@/components/ui/flex';6import { Stack } from '@/components/ui/stack';78const checks = [9 { name: 'Unit tests', detail: '412 passed in 38s', label: 'Passed', icon: CheckIcon },10 { name: 'Type check', detail: 'Running on node 22', label: 'Running', icon: LoaderIcon },11 { name: 'Bundle size', detail: '+12kb over budget', label: 'Warning', icon: AlertTriangleIcon },12] as const;1314const variants = {15 Passed: 'success',16 Running: 'info',17 Warning: 'warning',18} as const;1920export function WithIcon() {21 return (22 <Stack gap="4" className="border-border bg-card w-full max-w-md rounded-xl border p-4">23 {checks.map((check) => (24 <Flex key={check.name} align="center" justify="between" gap="4">25 <div className="min-w-0">26 <p className="truncate text-sm font-medium">{check.name}</p>27 <p className="text-muted-foreground truncate text-xs">{check.detail}</p>28 </div>29 <Badge variant={variants[check.label]}>30 <check.icon className="size-3" size={12} />31 {check.label}32 </Badge>33 </Flex>34 ))}35 </Stack>36 );37}
API Reference
Badge
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'secondary' | 'destructive' | 'outline' | 'default' | Visual style |
className | string | - | Additional CSS classes |
Found something to improve?
Notice a bug, typo, or missing detail on this page? Help us make the documentation better by opening a GitHub issue.