Skip to main content
Urbicon UI

Badge

Compact labels for status, categories, and counts with multiple visual styles.

Playground

New
Variant
Size Style variant (tailwind-variants)
Tier Style variant (tailwind-variants)
<Badge>New</Badge>

01 Examples

Border (visual separation on colored surfaces)

The border prop adds a 2px ring in the page surface color — invisible on the default page background, but it cuts a clean halo when the badge overlays a colored avatar, image, or button.
JD
JD
AB 5
<div
  class="bg-primary relative flex h-16 w-16 items-center justify-center rounded-full text-white"
>
  JD
  <Badge intent="success" variant="dot" placement="bottom-end" />
</div>
<div
  class="bg-primary relative flex h-16 w-16 items-center justify-center rounded-full text-white"
>
  JD
  <Badge intent="success" variant="dot" placement="bottom-end" border />
</div>
<div
  class="bg-warning text-text-on-warning relative flex h-16 w-16 items-center justify-center rounded-full"
>
  AB
  <Badge intent="danger" counter placement="top-end" border size="sm">5</Badge>
</div>

Notification Counter

3
12
<div class="relative inline-block">
  <Button variant="outlined" intent="neutral">Inbox</Button>
  <Badge intent="danger" counter placement="top-end" border size="sm">3</Badge>
</div>
<div class="relative inline-block">
  <Button variant="outlined" intent="neutral">Updates</Button>
  <Badge intent="primary" counter placement="top-end" border size="sm">12</Badge>
</div>
<div class="relative inline-block">
  <Button variant="outlined" intent="neutral">Alerts</Button>
  <Badge intent="success" variant="dot" placement="top-end" border />
</div>

02 Patterns

Badge serves five distinct use cases that look alike but behave differently. Picking the right pattern up-front avoids API-shape regret later — particularly around removable vs interactive, counter sizing, and placement-anchoring. The purpose axis makes that taxonomy first-class: status / tag / counter / dot / chip orchestrate the low-level visual props, so you rarely set them by hand. One of them also picks a colour: purpose="tag" defaults to intent="neutral", because a category (a stage, a type, a version) carries no severity — painting one as a status is the most common colour defect there is. Pass intent explicitly to override.

1. Status Tag — stateful label

Communicate the current state of an entity (Active/Inactive, Draft/Published, Online/Offline). Use variant=soft for ambient lists, variant=outlined for higher-contrast tables. Never removable, never a number.
Active Pending Suspended Draft Published
<Badge variant="soft" intent="success">Active</Badge>
<Badge variant="soft" intent="warning">Pending</Badge>
<Badge variant="soft" intent="danger">Suspended</Badge>
<Badge variant="outlined" intent="neutral">Draft</Badge>
<Badge variant="outlined" intent="primary">Published</Badge>

2. Counter — numeric pill

counter locks min-width to height, so a single digit renders as a circle rather than a squat pill — the first badge below is the same intent without it, for comparison. It holds 1–3 digits cleanly. Always pair with a placement when anchoring to a Button or Avatar — see the Notification Counter example above.
3 unread 3 12 99+ 247
<Badge intent="primary" size="sm">3 unread</Badge>
<Badge intent="primary" counter size="sm">3</Badge>
<Badge intent="danger" counter size="sm">12</Badge>
<Badge intent="success" counter size="sm">99+</Badge>
<Badge intent="warning" counter>247</Badge>

3. Indicator Dot — presence/state marker

variant=dot strips all content and shrinks the badge to a presence indicator — typical on avatars (online/away/busy) or buttons (unread bell). Pair with border when overlaying a colored surface to cut a clean halo.
JD
AB
MK
<div
  class="bg-primary-subtle text-primary-emphasis relative flex h-10 w-10 items-center justify-center rounded-full text-sm font-bold"
>
  JD
  <Badge intent="success" variant="dot" placement="bottom-end" border />
</div>
<div
  class="bg-warning-subtle text-warning-emphasis relative flex h-10 w-10 items-center justify-center rounded-full text-sm font-bold"
>
  AB
  <Badge intent="warning" variant="dot" placement="bottom-end" border />
</div>
<div
  class="bg-danger-subtle text-danger-emphasis relative flex h-10 w-10 items-center justify-center rounded-full text-sm font-bold"
>
  MK
  <Badge intent="danger" variant="dot" placement="bottom-end" border />
</div>

4. Filter Chip — removable, user-applied

Use removable to show user-applied filters or selected tags that can be dismissed. Pair with onRemove. Press Delete / Backspace while focused to remove via keyboard.
Active Premium Last 7 days
{#each filters as filter (filter)}
  <Badge
    variant="soft"
    intent="primary"
    removable
    onRemove={() => removeFilter(filter)}
    size="sm"
  >
    {filter}
  </Badge>
{/each}
{#if filters.length === 0}
  <span class="text-text-tertiary text-sm">No filters · </span>
  <button
    class="text-primary text-sm underline"
    onclick={() => (filters = ['Active', 'Premium', 'Last 7 days'])}
  >
    reset
  </button>
{/if}

5. Inline Label — categorization in prose

Plain, read-only marker rendered inside a sentence or list item. Prefer variant=outlined or variant=soft over filled so the badge reads as taxonomy, not as a state change.

The Beta release adds support for OKLCH color tokens and a redesigned Tier API . Existing consumers can opt-in per component.

<p class="text-text-secondary text-sm leading-loose">
  The <Badge variant="outlined" intent="neutral" size="sm">Beta</Badge> release adds support for
  <Badge variant="soft" intent="primary" size="sm">OKLCH</Badge>
  color tokens and a redesigned
  <Badge variant="soft" intent="success" size="sm">Tier API</Badge>. Existing consumers can
  opt-in per component.
</p>

When to pick which

PatternKey PropRecommended Variant
Status Tagvariantsoft or outlined
Countercounter · placementfilled
Indicator Dotvariant="dot" · borderdot (locked)
Filter Chipremovable · onRemovesoft
Inline Labeloutlined or soft

Mixing patterns (e.g. counter + removable, or filter-chip with `intent=danger`) usually points at a different component — a deletable counter is a Chip, a danger-tinted filter is a state-tag of the search itself.

03 Customization

Gradient Tags

Use slotClasses to turn badges into vibrant category tags.
Featured New Release Trending
<Badge
  slotClasses={{
    base: 'bg-linear-to-r from-violet-500 to-fuchsia-500 text-white border-none shadow-md shadow-violet-500/20'
  }}
>
  Featured
</Badge>
<Badge
  slotClasses={{
    base: 'bg-linear-to-r from-cyan-500 to-blue-500 text-white border-none shadow-md shadow-cyan-500/20'
  }}
>
  New Release
</Badge>
<Badge
  slotClasses={{
    base: 'bg-linear-to-r from-amber-500 to-orange-500 text-white border-none shadow-md shadow-amber-500/20'
  }}
>
  Trending
</Badge>

Glassmorphism

Frosted glass badges over rich backgrounds.
PRO Beta Live
<Badge
  unstyled
  class="rounded-full border border-white/20 bg-white/15 px-3 py-1 text-xs font-medium text-white backdrop-blur-md"
>
  PRO
</Badge>
<Badge
  unstyled
  class="rounded-full border border-white/20 bg-white/15 px-3 py-1 text-xs font-medium text-white backdrop-blur-md"
>
  Beta
</Badge>
<Badge
  unstyled
  class="rounded-full border border-white/20 bg-white/15 px-3 py-1 text-xs font-medium text-white backdrop-blur-md"
  pulse
>
  Live
</Badge>

Neon Glow

High-contrast neon badges for dark interfaces.
Online Syncing Offline
<Badge
  unstyled
  class="rounded-full border border-emerald-400/60 bg-emerald-400/10 px-3 py-1 text-xs font-semibold text-emerald-400 shadow-[0_0_12px_rgba(52,211,153,0.3)]"
>
  Online
</Badge>
<Badge
  unstyled
  class="rounded-full border border-sky-400/60 bg-sky-400/10 px-3 py-1 text-xs font-semibold text-sky-400 shadow-[0_0_12px_rgba(56,189,248,0.3)]"
>
  Syncing
</Badge>
<Badge
  unstyled
  class="rounded-full border border-rose-400/60 bg-rose-400/10 px-3 py-1 text-xs font-semibold text-rose-400 shadow-[0_0_12px_rgba(251,113,133,0.3)]"
>
  Offline
</Badge>

Fully Custom (unstyled)

Drop all defaults and build a completely unique badge.
v2.4.0 Editor's Pick
<Badge
  unstyled
  class="text-text-primary inline-flex items-center gap-1.5 rounded-none border-2 border-current px-3 py-1 font-mono text-xs font-bold tracking-widest uppercase"
>
  v2.4.0
</Badge>
<Badge
  unstyled
  class="inline-flex items-center gap-1.5 rounded-2xl bg-linear-to-br from-amber-200 to-orange-300 px-4 py-1.5 text-xs font-bold text-neutral-900 shadow-lg"
>
  <StarIcon size={14} /> Editor's Pick
</Badge>

A tag style that repeats across the app — like the gradient categories above — is one BlocksProvider preset (presets.Badge) applied via preset, not a copied slotClasses block. See Customization.

04 Accessibility

Built-in ARIA

Badges render with role="status" by default, announcing content changes to screen readers. Removable badges include an accessible label for the remove button. Set role="alert" for time-sensitive notifications.

Keyboard

Interactive badges are focusable via Tab and activate with Enter / Space. Removable badges also respond to Delete / Backspace.

Reduced Motion

Pulse animations and Mint effects are suppressed when prefers-reduced-motion is enabled.

05 API Reference

22 props
22 props 1 required
Prop
Type
Default
Description

06 Types

Local type definitions used by this component.

8 types
Name
Kind
Category
Used by
Description

07 Installation

Import

import { Badge } from '@urbicon-ui/blocks';