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

# Status Element

> Embed a live, inline status panel with a single custom element

`<kodo-status>` is a drop-in [Web Component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
that renders a **live status panel inline** in your app's layout — right where
you place it. It shows overall status, active incidents, and each component
with its 90-day uptime, updating in real time over
[Server-Sent Events](/monitoring/uptime-monitors).

It renders inside a [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM),
so your site's CSS can't leak in and its styles can't leak out — yet you can
still theme it with a handful of CSS custom properties.

<Note>
  Prefer a floating badge or banner pinned to a corner? Use the
  [Status Widget](/integrations/widget) (`widget.js`) instead. Need a fully
  sandboxed embed? The classic `iframe` at `…/status/{slug}/embed` still works.
  The element is the best fit when you want status **in the flow of your own
  UI**, styled to match.
</Note>

## Quick start

```html theme={null}
<script src="https://kodostatus.com/embed.js" async></script>

<kodo-status slug="your-page-slug"></kodo-status>
```

Replace `your-page-slug` with the slug of a **public** status page. The script
defines the element once; every `<kodo-status>` on the page upgrades
automatically, even ones already in your HTML before the script loads. You only
need the `<script>` tag once, no matter how many elements you render.

The element self-configures its API origin from the script's own URL, so you
don't need to set `base` when loading `embed.js` from `kodostatus.com`.

## What it renders

* **Overall status** — a live-pulsing dot + label (e.g. "All Systems Operational").
* **Active incidents** — title + severity for anything unresolved.
* **Components** — each service with its status and, when a monitor is attached,
  its **90-day uptime %** and a **daily uptime sparkline**. Components without a
  monitor simply show their status (no fabricated uptime).

## Attributes

| Attribute    | Values                    | Default       | Description                                                                                   |
| ------------ | ------------------------- | ------------- | --------------------------------------------------------------------------------------------- |
| `slug`       | string                    | —             | **Required.** Your public status page slug.                                                   |
| `base`       | URL                       | script origin | API origin. Only needed if self-hosting Kōdo.                                                 |
| `theme`      | `auto` · `light` · `dark` | `auto`        | `auto` follows the visitor's `prefers-color-scheme`.                                          |
| `components` | `true` · `false`          | `true`        | Show the per-component list.                                                                  |
| `incidents`  | `true` · `false`          | `true`        | Show active incidents.                                                                        |
| `header`     | `true` · `false`          | `true`        | Show the overall-status header row.                                                           |
| `history`    | `true` · `false`          | `true`        | Show the 90-day uptime sparkline under each component.                                        |
| `compact`    | `true` · `false`          | `false`       | Hide descriptions and sparklines for a tighter list.                                          |
| `headless`   | `true` · `false`          | `false`       | Render nothing — fetch, subscribe, and emit events only. See [Headless mode](#headless-mode). |

```html theme={null}
<!-- Just the overall status pill -->
<kodo-status slug="acme" components="false"></kodo-status>

<!-- Tight component list, no sparklines, dark -->
<kodo-status slug="acme" theme="dark" compact="true"></kodo-status>
```

## Theming

Set any of these CSS custom properties on the element (or an ancestor) — they
inherit through the Shadow DOM boundary. Semantic status colors (green / amber /
red) are intentionally fixed so health stays legible.

| Property        | Purpose                  |
| --------------- | ------------------------ |
| `--kodo-bg`     | Panel background         |
| `--kodo-fg`     | Text color               |
| `--kodo-muted`  | Secondary / muted text   |
| `--kodo-border` | Borders and dividers     |
| `--kodo-card`   | Incident card background |
| `--kodo-radius` | Corner radius            |
| `--kodo-font`   | Font family              |

```html theme={null}
<style>
  kodo-status {
    --kodo-radius: 6px;
    --kodo-font: "Inter", system-ui, sans-serif;
    --kodo-border: rgba(37, 99, 235, 0.2);
  }
</style>
<kodo-status slug="acme" theme="light"></kodo-status>
```

## Events

The element emits two events. Both bubble and are `composed`, so you can listen
on the element itself, on `window`, or on any ancestor — including from outside a
host Shadow DOM.

| Event                | Fires                                            | `event.detail`                                                |
| -------------------- | ------------------------------------------------ | ------------------------------------------------------------- |
| `kodo:snapshot`      | On **every** update (initial + each live change) | `{ slug, status, previousStatus, activeIncidents, snapshot }` |
| `kodo:status-change` | Only when the **overall status transitions**     | same shape                                                    |

```js theme={null}
window.addEventListener("kodo:status-change", (e) => {
  const { slug, status, previousStatus } = e.detail;
  if (status !== "operational") {
    // e.g. show your own toast, badge, or banner
    console.warn(`${slug}: ${previousStatus} → ${status}`);
  }
});
```

## Properties

Read the latest data off the element at any time:

```js theme={null}
const el = document.querySelector("kodo-status");
el.status; // "operational" | "degraded" | … | null (before first load)
el.data;   // the full snapshot object, or null
```

## Headless mode

Add `headless` and the element renders **nothing** — it just fetches, subscribes
to live updates, and emits events. This is the escape hatch for building a
completely custom UI on Kōdo's live status, with none of the built-in styling:

```html theme={null}
<kodo-status id="status" headless slug="acme"></kodo-status>

<script>
  const el = document.getElementById("status");
  el.addEventListener("kodo:snapshot", (e) => {
    const { status, snapshot } = e.detail;
    // Render however you like — a nav dot, a custom bar, your own component…
    document.body.dataset.systemStatus = status;
    myRenderStatus(snapshot);
  });
</script>
```

You get the same real-time SSE stream and the same `.data` / `.status`
properties — just no DOM from Kōdo. It's the lightest possible way to wire live
status into a design system that owns its own rendering.

## Frameworks

Custom elements are just HTML, so they work in any framework.

<CodeGroup>
  ```jsx React / Next.js theme={null}
  // Attributes are plain strings — pass them directly.
  // In Next.js, load the script once (e.g. in the layout) and drop the tag anywhere.
  import Script from "next/script";

  export default function Status() {
    return (
      <>
        <Script src="https://kodostatus.com/embed.js" strategy="afterInteractive" />
        <kodo-status slug="acme" theme="auto"></kodo-status>
      </>
    );
  }
  ```

  ```vue Vue theme={null}
  <!-- Tell Vue to treat kodo-status as a custom element (vite.config):
       vue({ template: { compilerOptions: { isCustomElement: t => t === 'kodo-status' } } }) -->
  <template>
    <kodo-status slug="acme" theme="auto" />
  </template>

  <script setup>
  import "https://kodostatus.com/embed.js";
  </script>
  ```

  ```html Plain HTML theme={null}
  <script src="https://kodostatus.com/embed.js" async></script>
  <kodo-status slug="acme"></kodo-status>
  ```
</CodeGroup>

## Live updates & resilience

The element paints instantly from the cached JSON endpoint, then subscribes to
the SSE stream for real-time changes. If `EventSource` isn't available it falls
back to polling. Uptime figures are fetched once and preserved across live
status updates, so the panel never flickers its history.

<Tip>
  The element only reads **public** status pages. Keep sensitive components on a
  private or audience-restricted page and they won't appear in an embed.
</Tip>
