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

# Components

The `@wisdomai/react` package gives you several ways to embed analytics, from a whole dashboard down to a single visualization you wrap in your own card. All of them live inside a `WisdomProvider` (see [Quickstart](/integrations/embeddings/sdk/sdk-quickstart)).

## Embed a full dashboard

The `<Dashboard>` component renders an entire Wisdom dashboard, including the header, filter bar, and widget grid:

```tsx theme={null}
import { WisdomProvider, Dashboard } from '@wisdomai/react';
 
<WisdomProvider theme={/* ... */}>
  <Dashboard dashboardId="<your-dashboard-id>" />
</WisdomProvider>
```

## Embed a single widget

Prefer to place one chart or metric on its own? Render a single widget instead of the whole dashboard:

```tsx theme={null}
import { WisdomProvider, DashboardWidget } from '@wisdomai/react';
 
<WisdomProvider theme={/* ... */}>
  <DashboardWidget dashboardId="<your-dashboard-id>" widgetId="<widget-id>" />
</WisdomProvider>
```

## Composable widgets (advanced)

When you want full control over the card *around* a widget, including your own container, header, spacing, menus, and empty/loading states, drop down to the composable layer. Instead of Wisdom's pre-built widget card, you render just the visualization and wrap it in your own markup.

```tsx theme={null}
import {
  WisdomProvider,
  DashboardProvider,
  useDashboardWidget,
  WisdomVisualization,
} from '@wisdomai/react';
 
function BrandCard({ widgetId }: { widgetId: string }) {
  const { widget, status, error, fetchMore } = useDashboardWidget(widgetId);
 
  if (status === 'loading') return <YourSkeleton />;
  if (error || !widget) return <YourError message={error} />;
 
  return (
    <section className="your-card">
      <h3>{widget.title}</h3>
      <WisdomVisualization visualization={widget.visualization} fetchMore={fetchMore} />
    </section>
  );
}
 
export default function App() {
  return (
    <WisdomProvider theme={/* ... */}>
      <DashboardProvider dashboardId="<your-dashboard-id>">
        <BrandCard widgetId="<widget-id>" />
      </DashboardProvider>
    </WisdomProvider>
  );
}
```

`DashboardProvider` loads the dashboard once; each `useDashboardWidget(widgetId)` reads a widget from it and returns the live `visualization` plus a `fetchMore` callback for paginating large series. `WisdomVisualization` renders the chart, metric, or table itself, with no Wisdom-supplied title bar or kebab menu, so the surrounding card is entirely yours.

<Note>
  The composable layer (`DashboardProvider`, `useDashboardWidget`, `WisdomVisualization`) is the lower-level building block beneath `Dashboard` and `DashboardWidget`. Reach for it whenever you want full control over the UI around a widget. As the SDK is still pre-1.0 (`0.0.x`), these APIs may see small changes between releases. Let your Wisdom contact know what you're building and we'll give you a heads-up on anything that affects you.
</Note>

## Filters

Wisdom dashboards can be filtered three ways, from zero-effort to fully custom.

**1. Built-in filter bar (default).** `<Dashboard>` already renders a filter bar above its widgets, so your end users can filter without any extra work on your side.

**2. Decoupled filters: place the filter UI anywhere.** To move the filter controls out of the dashboard and into your own layout, such as a sidebar, a toolbar, or a drawer, compose the pieces under a single `DashboardProvider`. The filters and the widgets share that provider's state, so controls placed anywhere drive the same dashboard:

```tsx theme={null}
import {
  WisdomProvider,
  DashboardProvider,
  DashboardFilters,
  DashboardWidgets,
} from '@wisdomai/react';
 
<WisdomProvider theme={/* ... */}>
  <DashboardProvider dashboardId="<your-dashboard-id>">
    <aside className="your-sidebar">
      <DashboardFilters direction="column" />
    </aside>
    <main>
      <DashboardWidgets />
    </main>
  </DashboardProvider>
</WisdomProvider>
```

`DashboardFilters` takes a `direction` of `'row'` (default) or `'column'`. Because `DashboardFilters` and `DashboardWidgets` read the **same** `DashboardProvider`, the filter controls drive the widgets no matter where you place them in your layout. The controls must share a provider with the widgets. A `DashboardFilters` placed next to a self-contained `<Dashboard>` (which creates its own provider internally) will not drive it.

<Note>
  Decoupled filters use the composable layer (`DashboardProvider` + `DashboardWidgets`) described above. The all-in-one `<Dashboard>` already includes the built-in filter bar, so use this approach when you want to place the filter controls somewhere `<Dashboard>` won't put them.
</Note>

**3. Headless: drive filters from your own state.** For full control, `useDashboardFilters()` (called inside a `DashboardProvider`) returns the live filter specs plus a `setFilterValue(filterId, value)` mutator, so you can build your own filter inputs and apply them programmatically.

## Next steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="Key" href="/integrations/embeddings/sdk/sdk-auth">
    Secure your integration that keeps your access token on the server and out of the browser.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/integrations/embeddings/sdk/sdk-quickstart">
    Set up the SDK and embed your first dashboard in minutes.
  </Card>
</CardGroup>
