> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nozle.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# UsageDashboard

> A card of usage meters, one per limited feature, with loading, error and empty states.

`UsageDashboard` shows several [`UsageMeter`](/sdks/react/components/usage-meter)s in one card, one per feature.

**When to use**

* A "Usage" tab in your billing or account settings.
* A dashboard card that shows the customer's limits.
* Several limits at once, limited and unlimited, with the meter's colour thresholds.

**Light**

![UsageDashboard with API calls at 62%, seats at 90% and storage at 98%, light theme](https://mintcdn.com/nozle-d78f01d8/FWVI_xhrW09Oexco/images/react/components/usage-dashboard/light.png?fit=max\&auto=format\&n=FWVI_xhrW09Oexco\&q=85\&s=901bc1273cdfeb2718c450068e52cbf1)

**Dark**

![UsageDashboard with API calls at 62%, seats at 90% and storage at 98%, dark theme](https://mintcdn.com/nozle-d78f01d8/FWVI_xhrW09Oexco/images/react/components/usage-dashboard/dark.png?fit=max\&auto=format\&n=FWVI_xhrW09Oexco\&q=85\&s=d0652e31091c601e9e1a79ab324a141c)

**Minimal**

![UsageDashboard with API calls at 62%, seats at 90% and storage at 98%, minimal theme](https://mintcdn.com/nozle-d78f01d8/FWVI_xhrW09Oexco/images/react/components/usage-dashboard/minimal.png?fit=max\&auto=format\&n=FWVI_xhrW09Oexco\&q=85\&s=7d2c0018a275d8d716d22bf97c4e488e)

**Neobrutal**

![UsageDashboard with API calls at 62%, seats at 90% and storage at 98%, neobrutal theme](https://mintcdn.com/nozle-d78f01d8/FWVI_xhrW09Oexco/images/react/components/usage-dashboard/neobrutal.png?fit=max\&auto=format\&n=FWVI_xhrW09Oexco\&q=85\&s=b60927d5772e6a79bec2683c0f350539)

**Nozle**

![UsageDashboard with API calls at 62%, seats at 90% and storage at 98%, nozle theme](https://mintcdn.com/nozle-d78f01d8/FWVI_xhrW09Oexco/images/react/components/usage-dashboard/nozle.png?fit=max\&auto=format\&n=FWVI_xhrW09Oexco\&q=85\&s=f35b8f7e45c142e3d1389747cbac33df)

**Nozle Dark**

![UsageDashboard with API calls at 62%, seats at 90% and storage at 98%, nozleDark theme](https://mintcdn.com/nozle-d78f01d8/FWVI_xhrW09Oexco/images/react/components/usage-dashboard/nozle-dark.png?fit=max\&auto=format\&n=FWVI_xhrW09Oexco\&q=85\&s=b93a0b3fbddb502b31aceec38f8a51f0)

## Importing UsageDashboard

```tsx theme={null}
import {
  UsageDashboard,
  usageItems,
  type UsageDashboardFeature,
  type UsageResult,
} from '@nozle-js/react'
```

## Rendering UsageDashboard

Pass one row per feature:

```tsx components/usage-card.tsx theme={null}
export function UsageCard() {
  return (
    <UsageDashboard
      features={[
        { key: 'api_calls', label: 'API calls', used: 31200, limit: 50000 },
        { key: 'seats', label: 'Seats', used: 9, limit: 10 },
      ]}
    />
  )
}
```

Each row renders a labelled `UsageMeter` with its colour thresholds.

## Data

Each row is a `UsageDashboardFeature`: `{ key, label, used, limit? }`. A `limit` of `null`, or no `limit`, means unlimited.

```tsx theme={null}
const features: UsageDashboardFeature[] = [
  { key: 'api_calls', label: 'API calls', used: 31200, limit: 50000 },
  { key: 'projects', label: 'Projects', used: 12, limit: null },
]

export function Usage() {
  return <UsageDashboard features={features} />
}
```

> **Full example data**
>
> ```tsx theme={null}
> const features: UsageDashboardFeature[] = [
>   { key: 'api_calls', label: 'API calls', used: 31200, limit: 50000 },
>   { key: 'seats', label: 'Seats', used: 9, limit: 10 },
>   { key: 'storage', label: 'Storage (GB)', used: 98, limit: 100 },
>   { key: 'projects', label: 'Projects', used: 12, limit: null },
> ]
>
> export function Usage() {
>   return <UsageDashboard features={features} />
> }
> ```

### Live data

`usageItems(entitlements, results)` joins a plan's metered entitlements from the catalog (for the names) with usage results keyed by feature code, the `used` and `limit` of a `can()` result. Entitlements that are not metered, or have no result, are left out.

```tsx theme={null}
import { useEntitlement, usePlans, useSubscription } from '@nozle-js/react'

export function LiveUsage() {
  const subscription = useSubscription()
  const { plans } = usePlans()
  const apiCalls = useEntitlement('api_calls')
  const seats = useEntitlement('seats')

  const plan = plans.find((entry) => entry.code === subscription.data?.subscription?.plan_code)
  const results: Record<string, UsageResult | undefined> = {
    api_calls: apiCalls.data && { used: apiCalls.data.used ?? 0, limit: apiCalls.data.limit },
    seats: seats.data && { used: seats.data.used ?? 0, limit: seats.data.limit },
  }
  return (
    <UsageDashboard
      features={usageItems(plan?.entitlements ?? [], results)}
      loading={subscription.isPending || apiCalls.isPending || seats.isPending}
      error={subscription.error ?? apiCalls.error ?? seats.error}
    />
  )
}
```

`currentPlanMeters(entitlements, usage)` builds the same rows from this period's `charges_usage` instead; see [`CurrentPlan`](/sdks/react/components/current-plan#live-data).

## Examples

### Loading, empty and error

`loading` shows three skeleton rows, an empty `features` list shows `emptyMessage`, and `error` shows the message instead of the rows.

![UsageDashboard skeleton, No usage to show yet message, and an error message, light theme](https://mintcdn.com/nozle-d78f01d8/FWVI_xhrW09Oexco/images/react/components/usage-dashboard-states/light.png?fit=max\&auto=format\&n=FWVI_xhrW09Oexco\&q=85\&s=4843bd88d3480a73de784b0c23566630)

```tsx theme={null}
export function UsageStates() {
  return (
    <>
      <UsageDashboard loading />
      <UsageDashboard features={[]} />
      <UsageDashboard error="Usage could not be loaded." />
    </>
  )
}
```

### Unlimited feature

A row without a limit reads "Unlimited" and its bar stays empty.

```tsx theme={null}
export function ProjectsUsage() {
  return <UsageDashboard features={[{ key: 'projects', label: 'Projects', used: 12, limit: null }]} />
}
```

## API reference

**features** `UsageDashboardFeature[]`

The rows: `{ key, label, used, limit? }`. `limit` `null` or missing means unlimited. Defaults to `[]`.

**loading** `boolean` (default: false)

Shows three skeleton rows.

**error** `Error | string | null`

Shows the message in a `role="alert"` card instead of the rows. Defaults to `null`.

**emptyMessage** `string` (default: No usage to show yet.)

Shown when `features` is empty.

**appearance** `Appearance`

Theme, variables and element overrides, also passed to each meter. Defaults to the provider's. See [Appearance](/sdks/react/styling).

### States

| State | What shows |
| - | - |
| `loading` | Three skeleton rows. |
| `error` set | The message in a `role="alert"` card, in the danger text colour. |
| No features | `emptyMessage` in a `role="status"` card. |

### Appearance

> **Element keys**
>
> `usageDashboard` (the card), and the [`UsageMeter`](/sdks/react/components/usage-meter#appearance) elements for each row.
>
> Style them with `appearance.elements`. See [Elements](/sdks/react/styling#elements).

## Related

> **[UsageMeter](/sdks/react/components/usage-meter)**
>
> One meter on its own.

> **[UsageBreakdown](/sdks/react/components/usage-breakdown)**
>
> Units and amounts of this period.

> **[CurrentPlan](/sdks/react/components/current-plan)**
>
> The plan with its meters built for you.

> **[UsageAlert](/sdks/react/components/usage-alert)**
>
> A warning when a limit is close.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.