Skip to content
Facade UI
Colour mode
GitHub (opens in a new tab)
uiatom

Badge

Small inline label for status or category, with an optional screen-reader prefix.

Preview

Open full width (opens in a new tab)
Preview width

Installation

Package manager
pnpm dlx shadcn@latest add https://facadeui.dev/r/badge.json

Pulls in class-variance-authority@^0.7.1, utils. The CLI installs them for you.

Usage

The exact source of the preview above.

demos/badge.tsx
import { SparklesIcon } from "lucide-react"

import { Badge } from "@registry/ui/badge"

export function Demo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Badge>Default</Badge>
      <Badge variant="primary">
        <SparklesIcon aria-hidden />
        New
      </Badge>
      <Badge variant="outline">Outline</Badge>
      <Badge variant="muted">Muted</Badge>
      <Badge variant="destructive" srLabel="Status: ">
        Deprecated
      </Badge>
      <Badge size="sm">Small</Badge>
    </div>
  )
}

Source

What the CLI copies into your project, byte for byte.

components/ui/badge.tsx
/**
 * Badge — a small inline label for status, category, or a "New" marker.
 *
 * a11y: purely presentational by default. A badge that conveys information not
 * available elsewhere in the surrounding text needs an accessible name of its
 * own — pass `srLabel` for that ("Status: ") rather than relying on colour or
 * position to carry the meaning.
 *
 * Dependencies: class-variance-authority, react, @/lib/utils.
 */

import { cva, type VariantProps } from "class-variance-authority"
import type { ComponentPropsWithoutRef, ReactNode } from "react"

import { cn } from "@/lib/utils"

export const badgeVariants = cva(
  [
    "inline-flex items-center gap-1.5 whitespace-nowrap rounded-full border font-medium",
    "[&_svg:not([class*='size-'])]:size-3.5 [&_svg]:pointer-events-none [&_svg]:shrink-0",
  ],
  {
    variants: {
      variant: {
        default: "bg-secondary text-secondary-foreground border-transparent",
        primary: "bg-primary text-primary-foreground border-transparent",
        outline: "border-border bg-background text-foreground",
        muted: "bg-muted text-muted-foreground border-transparent",
        destructive: "bg-destructive text-destructive-foreground border-transparent",
      },
      size: {
        sm: "px-2 py-0.5 text-xs",
        md: "px-2.5 py-1 text-sm",
      },
    },
    defaultVariants: { variant: "default", size: "md" },
  },
)

export interface BadgeProps
  extends ComponentPropsWithoutRef<"span">, VariantProps<typeof badgeVariants> {
  /** Visually hidden prefix, for badges whose meaning is not in the visible text. */
  srLabel?: string
  children?: ReactNode
}

export function Badge({
  variant,
  size,
  srLabel,
  className,
  children,
  ...props
}: BadgeProps) {
  return (
    <span className={cn(badgeVariants({ variant, size }), className)} {...props}>
      {srLabel ? <span className="sr-only">{srLabel}</span> : null}
      {children}
    </span>
  )
}

Props

BadgeProps

Extends ComponentPropsWithoutRef<"span">, VariantProps<typeof badgeVariants>.

Props for BadgeProps
PropTypeDefault
srLabelVisually hidden prefix, for badges whose meaning is not in the visible text.string
childrenReactNode