Status
A pill or live indicator showing the current state of a resource.
Status reports what state something is in right now — a deployment, a payment, an API key. It describes a resource, not the page it sits on; for a message about the page or section, use Banner.
Variants
Neutral
<Status variant="neutral">Draft</Status>Info
<Status variant="info">Active</Status>Pending
<Status variant="pending">Deploying</Status>Warning
<Status variant="warning">Degraded</Status>| Variant | Meaning |
|---|---|
neutral | No state worth flagging — draft, archived, not started. |
info | Running normally. |
pending | In progress, expected to resolve on its own. |
warning | Working but degraded; may need attention. |
live | A live state that keeps updating, such as a system status feed. |
Live
live drops the pill and shows a label next to a pulsing dot, for a state
that is being watched as it happens, such as the health of a service. It
fits footers, headers and dashboards where the status sits in running text
rather than in a table.
Default
<Status variant="live">All Systems Operational</Status>Live states
Status does not fetch anything. Your app reads the state from its source and passes the label, and a text colour class when the state is not normal. The dot and the label both use the text colour.
Minor Service Outage
Partial System Outage
Major System Outage
<Status variant="live">All Systems Operational</Status>
<Status variant="live" className="text-bds-yellow-70">Minor Service Outage</Status>
<Status variant="live" className="text-bds-orange-70">Partial System Outage</Status>
<Status variant="live" className="text-bds-red-70">Major System Outage</Status>Keep the label specific to the state. The colour helps people who can see it, but the label is the only thing a screen reader announces.
Live inside a Link
Wrap it in Link to send people to the full status page.
Status stays a span, so the link owns focus, hover and the accessible name.
<Link href="https://status.example.com" target="_blank" rel="noreferrer">
<Status variant="live">All Systems Operational</Status>
</Link>The dot pings outward once a second. When the reader has turned on reduced
motion, the ring is hidden and the dot stays still. live has one size and
ignores size. Pass icon to replace the dot, or null to remove it.
Sizes
Small
Small
<Status size="sm" variant="info">
Small
</Status>Medium
Medium
<Status size="md" variant="info">
Medium
</Status>sm is the default and fits inside table rows and list items. Use md when
the status is the primary content of its own region.
Indicator
Custom indicator
Syncing
<Status variant="pending" icon={<span className="size-2 motion-safe:animate-pulse rounded-full bg-current" />}>
Syncing
</Status>No indicator
No indicator
<Status variant="warning" icon={null}>
No indicator
</Status>icon defaults to a shape distinct per variant (a plain dot for neutral,
otherwise its semantic icon), so state is never colour alone. Replace it for
a custom indicator, or pass null (or false) where the label alone is
enough, for example in a table column already headed "Status".
When to use
Use Status for the current state of a resource — a deployment, a payment, an API key.
Use something else when:
- The message is about the page or section it sits in. Use Banner.
- You need a count. Use Badge.
- You only need to mark something as new. Use Unread.
Use the live variant when the state updates while people watch, such as
the health of a service, and the static pills for a state that changes only
when someone acts on it.
Usage
Do
Keep the label to one or two words in the resource's own vocabulary — "Deploying", "Failed", "Rate limited".
Don't
Rely on colour alone to distinguish states. The label is what a colour-blind reader and a screen reader both get.
Props
| Prop | Type | Default |
|---|---|---|
icon | TypeReactNode | Default— |
size | Type"sm" | "md" | null | Defaultsm |
variant | Type"neutral" | "info" | "pending" | "warning" | "live" | null | Defaultneutral |
Accessibility
Status renders a span with no implicit role, so its text is read inline as
ordinary content. When the state changes while the page is open and the reader
needs to know, put the Status inside a container with aria-live="polite" —
the component does not announce itself.
Every pill variant's label meets 4.5:1 contrast against its pill in light and dark themes, so the text stays readable at the small size. The icon repeats the state as a shape, so colour is never the only signal.
In the live variant the dot is hidden from assistive technology, so only the
label is read. The pulse runs only when the reader has not asked for reduced
motion. Put a live Status that changes while the page is open inside an
aria-live="polite" container, as above. Inside a Link, the label becomes the
link's accessible name.
The label never wraps, so keep it to a word or two; a long one pushes the pill wider rather than breaking it.