Badge
Displays a badge or a component that looks like a badge.
Loading…
import { Badge } from "@/components/ui/badge";export default function BadgeDemo() { return ( <div className="flex w-full flex-wrap justify-center gap-2"> <Badge>Badge</Badge> <Badge variant="secondary">Secondary</Badge> <Badge variant="destructive">Destructive</Badge> <Badge variant="outline">Outline</Badge> </div> );}Installation
npx shadcn@latest add @cortexcn/badgeCopy and paste the following code into your project.
import * as React from "react";import { cva, type VariantProps } from "class-variance-authority";import { Slot } from "radix-ui";import { cn } from "@/lib/utils";const badgeVariants = cva( "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3", { variants: { variant: { default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90", secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", destructive: "bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90", outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground", link: "text-primary underline-offset-4 [a&]:hover:underline", }, }, defaultVariants: { variant: "default", }, },);function Badge({ className, variant = "default", asChild = false, ...props}: React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) { const Comp = asChild ? Slot.Root : "span"; return ( <Comp data-slot="badge" data-variant={variant} className={cn(badgeVariants({ variant }), className)} {...props} /> );}export { Badge, badgeVariants };Update the import paths to match your project setup.
Usage
import { Badge } from "@/components/ui/badge";<Badge variant="default | secondary | destructive | outline | ghost | link">
Badge
</Badge>Examples
Variants
Use the variant prop to change the variant of the badge.
Loading…
import { Badge } from "@/components/ui/badge";export default function BadgeVariants() { return ( <div className="flex flex-wrap gap-2"> <Badge>Default</Badge> <Badge variant="secondary">Secondary</Badge> <Badge variant="destructive">Destructive</Badge> <Badge variant="outline">Outline</Badge> <Badge variant="ghost">Ghost</Badge> </div> );}With Icon
You can render an icon inside the badge. Use data-icon="inline-start" for a leading icon and data-icon="inline-end" for a trailing icon.
Loading…
import { BadgeCheck, BookmarkIcon } from "lucide-react";import { Badge } from "@/components/ui/badge";export default function BadgeWithIcon() { return ( <div className="flex flex-wrap gap-2"> <Badge variant="secondary"> <BadgeCheck data-icon="inline-start" /> Verified </Badge> <Badge variant="outline"> Bookmark <BookmarkIcon data-icon="inline-end" /> </Badge> </div> );}With Spinner
Render a spinner inside the badge to show a loading state.
Loading…
import { Badge } from "@/components/ui/badge";import { Spinner } from "@/components/ui/spinner";export default function BadgeWithSpinner() { return ( <div className="flex flex-wrap gap-2"> <Badge variant="destructive"> <Spinner data-icon="inline-start" /> Deleting </Badge> <Badge variant="secondary"> Generating <Spinner data-icon="inline-end" /> </Badge> </div> );}Link
Use the asChild prop to render a link as a badge.
Loading…
import { ArrowUpRightIcon } from "lucide-react";import { Badge } from "@/components/ui/badge";export default function BadgeAsLink() { return ( <Badge asChild> <a href="#link"> Open Link <ArrowUpRightIcon data-icon="inline-end" /> </a> </Badge> );}Custom Colors
Customize the colors of a badge by adding custom classes such as bg-green-50 dark:bg-green-800.
Loading…
import { Badge } from "@/components/ui/badge";export default function BadgeCustomColors() { return ( <div className="flex flex-wrap gap-2"> <Badge className="bg-blue-50 text-blue-700 dark:bg-blue-950 dark:text-blue-300"> Blue </Badge> <Badge className="bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-300"> Green </Badge> <Badge className="bg-sky-50 text-sky-700 dark:bg-sky-950 dark:text-sky-300"> Sky </Badge> <Badge className="bg-purple-50 text-purple-700 dark:bg-purple-950 dark:text-purple-300"> Purple </Badge> <Badge className="bg-red-50 text-red-700 dark:bg-red-950 dark:text-red-300"> Red </Badge> </div> );}RTL
Badges respect the document direction — pass dir="rtl" to flip the layout.
Loading…
"use client";import * as React from "react";import { BadgeCheck, BookmarkIcon } from "lucide-react";import { Badge } from "@/components/ui/badge";import { Button } from "@/components/ui/button";const content = { ltr: { dir: "ltr" as const, badge: "Badge", secondary: "Secondary", verified: "Verified", bookmark: "Bookmark", }, rtl: { dir: "rtl" as const, badge: "شارة", secondary: "ثانوي", verified: "متحقق", bookmark: "إشارة مرجعية", },};export default function BadgeRtl() { const [mode, setMode] = React.useState<"rtl" | "ltr">("rtl"); const t = content[mode]; return ( <div className="flex flex-col items-center gap-6"> <Button variant="ghost" size="sm" onClick={() => setMode((m) => (m === "rtl" ? "ltr" : "rtl"))} > Toggle dir ({mode}) </Button> <div className="flex flex-wrap justify-center gap-2" dir={t.dir}> <Badge>{t.badge}</Badge> <Badge variant="secondary">{t.secondary}</Badge> <Badge variant="secondary"> <BadgeCheck data-icon="inline-start" /> {t.verified} </Badge> <Badge variant="outline"> {t.bookmark} <BookmarkIcon data-icon="inline-end" /> </Badge> </div> </div> );}API Reference
Badge
| Prop | Type | Default |
|---|---|---|
variant | "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | "default" |
asChild | boolean | false |