> ## 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)).

This page covers the following components:

* [Embed a full dashboard](#embed-a-full-dashboard)
* [Chat](#chat)
* [DashChat](#dashchat)
* [Embed a single widget](#embed-a-single-widget)
* [Composable widgets (advanced)](#composable-widgets-advanced)
* [Filters](#filters)

## 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>
```

## Chat

Embed a conversation surface: viewers ask questions in natural language and answers stream back as charts, tables, and narratives, each in a titled card. Chat does not require a dashboard, wrap the conversation components in `ConversationProvider`:

```tsx theme={null}
import {
  WisdomProvider,
  ConversationProvider,
  Conversation,
  ConversationMessages,
  useConversation,
} from '@wisdomai/react';

function Chat() {
  const { submit, messages, user } = useConversation();
  return (
    <Conversation onSubmit={submit}>
      <ConversationMessages messages={messages} user={user} />
    </Conversation>
  );
}

<WisdomProvider theme={/* ... */}>
  <ConversationProvider>
    <Chat />
  </ConversationProvider>
</WisdomProvider>
```

What viewers get:

* Streamed answers as they are generated, with charts, tables, and narratives rendered as titled cards in the thread.
* An inline clarification form when more detail is needed to answer, instead of a guess.
* Suggested follow-up questions, message timestamps, and an explicit error row when a message fails.
* A "Show data" toggle that reveals the table behind an answer chart, and an "Export as…" menu for saving a chart as an image.

The conversation is created on the first submitted question. On its own, Chat has no domain preselected: set one from your own UI via `setDomainId` (returned by `useConversation()`). Inside a dashboard the domain comes from the dashboard automatically, that is DashChat, below.

Building blocks: `ConversationProvider`, `Conversation`, `ConversationInput`, `ConversationMessages`, `ClarificationForm`, the `useConversation` / `useConversationChat` hooks, and `ConversationsAPI` for programmatic create/send.

## DashChat

DashChat is Chat attached to a dashboard: a side panel scoped to the dashboard's own domains, so viewers ask follow-up questions about the same data the widgets are built on. One prop turns it on:

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

* The panel selects a domain from the dashboard's own domains, so answers come from the same governed data as the widgets. (`DashboardDomainSelector` renders the matching domain picker.)
* The dashboard and the panel split the width proportionally, and the panel has a show/hide toggle. Pass `height` (a number is pixels, `"100vh"` fills the viewport) so the widgets grid and the panel scroll independently while the header and filters stay pinned.
* Every widget gains an **Ask a follow-up question** action in its menu, which pre-fills the chat input with a question about that widget.

<Note>
  Chat and DashChat ship in `@wisdomai/react@0.0.12`, currently published on the `next` npm tag: `npm install @wisdomai/react@next`.
</Note>

## 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>
