---
name: badge
title: Badge
url: https://ui.frontic.com/components/ui/badge.md
tier: ui
install: npx @frontic/ui add badge
files:
  - components/ui/badge/Badge.vue
  - components/ui/badge/index.ts
dependencies:
  - class-variance-authority
  - reka-ui
---

# Badge

A short label such as new or sale, in the status colours and the commerce roles promo, discount, new and price, at three sizes.

## Install

```sh
npx @frontic/ui add badge
```

Used by: [Price](https://ui.frontic.com/components/ui/price.md), [Cart Summary](https://ui.frontic.com/components/sections/cart-summary.md), [Filters](https://ui.frontic.com/components/sections/filters.md), [Footer Trust](https://ui.frontic.com/components/sections/footer-trust.md), [Order Summary](https://ui.frontic.com/components/sections/order-summary.md), [Order Tracking](https://ui.frontic.com/components/sections/order-tracking.md), [Product Card Basic](https://ui.frontic.com/components/sections/product-card-basic.md), [Product Card Featured](https://ui.frontic.com/components/sections/product-card-featured.md), [Product Card Gallery](https://ui.frontic.com/components/sections/product-card-gallery.md), [Product Card Horizontal](https://ui.frontic.com/components/sections/product-card-horizontal.md), [Product Card Hover](https://ui.frontic.com/components/sections/product-card-hover.md), [Product Card Minimal](https://ui.frontic.com/components/sections/product-card-minimal.md), [Promo Code](https://ui.frontic.com/components/sections/promo-code.md), [Recent Orders](https://ui.frontic.com/components/sections/recent-orders.md), [Review Cards](https://ui.frontic.com/components/sections/review-cards.md), [Review List](https://ui.frontic.com/components/sections/review-list.md), [Search Suggestions](https://ui.frontic.com/components/sections/search-suggestions.md), [Shipping Address](https://ui.frontic.com/components/sections/shipping-address.md), [Team Members](https://ui.frontic.com/components/sections/team-members.md), [Cart Compact](https://ui.frontic.com/components/templates/cart-compact.md), [Cart Full](https://ui.frontic.com/components/templates/cart-full.md), [Cart Minimal](https://ui.frontic.com/components/templates/cart-minimal.md), [Category Filter](https://ui.frontic.com/components/templates/category-filter.md), [Category Grid](https://ui.frontic.com/components/templates/category-grid.md), [Checkout Page](https://ui.frontic.com/components/templates/checkout-page.md), [Filter Sheet](https://ui.frontic.com/components/templates/filter-sheet.md), [Filter Sidebar](https://ui.frontic.com/components/templates/filter-sidebar.md), [Filter Toolbar](https://ui.frontic.com/components/templates/filter-toolbar.md), [Header Centered](https://ui.frontic.com/components/templates/header-centered.md), [Header Shop](https://ui.frontic.com/components/templates/header-shop.md)

npm packages: `class-variance-authority`, `reka-ui`

## Examples

```vue
<script setup lang="ts">
import { Badge } from '@/components/ui/badge'
</script>

<template>
  <Badge variant="new">New</Badge>
</template>
```

## API reference

### Badge

Marks an item with a short label such as new or sale. Renders a `<span>`.

`data-slot="badge"` · `Badge.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` | `'span'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `variant` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'error' \| 'primary' \| 'promo' \| 'discount' \| 'new' \| 'price'` | `'neutral'` | What the badge marks: a state (info, success, warning, error), a commerce label (promo, discount, new, price), the brand colour (primary) or nothing in particular (neutral). Each takes its own colour and form. |
| `size` | `'md' \| 'sm' \| 'lg'` | `'md'` | The badge's padding and text size: sm keeps the smallest text, md and lg take the caption style. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-variant` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'error' \| 'primary' \| 'promo' \| 'discount' \| 'new' \| 'price'` | Carries the `variant` prop. |

## Styling

| Part | Recipe |
| --- | --- |
| `default` | [`badge`](https://ui.frontic.com/DESIGN.md#badge) |

States with a look of their own: hover and focus.

## Source

`components/ui/badge/Badge.vue`

```vue
<script lang="ts">
/** Marks an item with a short label such as new or sale. */
export default {}
</script>

<script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { cva, type VariantProps } from 'class-variance-authority'
import { Primitive } from 'reka-ui'

const badge = cva('fui-badge group/badge overflow-hidden whitespace-nowrap outline-none transition-colors **:data-icon:pointer-events-none', {
  variants: {
    variant: {
      neutral: 'fui-badge-neutral',
      primary: 'fui-badge-primary',
      info: 'fui-badge-info',
      success: 'fui-badge-success',
      warning: 'fui-badge-warning',
      error: 'fui-badge-error',
      promo: 'fui-badge-promo',
      discount: 'fui-badge-discount',
      new: 'fui-badge-new',
      price: 'fui-badge-price',
    },
    size: {
      sm: 'fui-badge-sm',
      md: 'fui-badge-md',
      lg: 'fui-badge-lg',
    },
  },
  defaultVariants: { variant: 'neutral', size: 'md' },
})

const props = withDefaults(
  defineProps<
    PrimitiveProps & {
      /** What the badge marks: a state (info, success, warning, error), a commerce label (promo, discount, new, price), the brand colour (primary) or nothing in particular (neutral). Each takes its own colour and form. */
      variant?: VariantProps<typeof badge>['variant']
      /** The badge's padding and text size: sm keeps the smallest text, md and lg take the caption style. */
      size?: VariantProps<typeof badge>['size']
      class?: HTMLAttributes['class']
    }
  >(),
  { as: 'span', variant: 'neutral', size: 'md' },
)
</script>

<template>
  <Primitive data-slot="badge" :data-variant="props.variant" :as="props.as" :as-child="props.asChild" :class="[badge({ variant: props.variant, size: props.size }), props.class]">
    <slot />
  </Primitive>
</template>
```
