Skip to main content
Deepgram's Docs

Search documentation

Type to search this documentation.

On this pageOverview

React UI Components

Bash

Import the stylesheet in your app’s entry point:

TSX
import "@deepgram/ui/styles.css";

The embedded widget below uses the components documented on this page — conversation panel, start button, microphone toggle, speaker toggle, text input, and the orb visualizer.

A complete voice agent interface in under 30 lines:

TSX
import {
  AgentProvider,
  AgentConversation,
  AgentTextInput,
  AgentStartButton,
  AgentMicrophoneButton,
  AgentSpeakerButton,
  Orb,
} from "@deepgram/ui";
import "@deepgram/ui/styles.css";
function App() {
  return (
    <AgentProvider
      config={{
        auth: { tokenFactory: () => fetch("/api/token").then((r) => r.text()) },
        agent: "YOUR_AGENT_ID",
      }}
    >
      <div data-dg-agent>
        <Orb size={120} />
        <AgentConversation />
        <AgentTextInput />
        <div>
          <AgentStartButton />
          <AgentMicrophoneButton />
          <AgentSpeakerButton />
        </div>
      </div>
    </AgentProvider>
  );
}

Replace YOUR_AGENT_ID with a Reusable Agent Configuration UUID, or pass an inline agent config object instead. See Agent Configuration for both patterns.

Every component is optional. Use one or all, and mix them with your own components inside the provider.

Renders the current connection state as a text label. Updates automatically as the session connects, disconnects, or reconnects.

Connected

TSX
<AgentStatus />

Props:

Prop Type Default Description
className string — Additional CSS class.
labels Partial<Record<string, string>> See below Override the display text for each state.

Default labels: "Not started", "Connecting...", "Connected", "Reconnecting...", "Disconnected".

TSX
<AgentStatus
  labels={{
    idle: "Ready",
    connecting: "Connecting...",
    connected: "Live",
    disconnected: "Offline",
  }}
/>

Data attributes: data-agent-status, data-state (current state value).

Scrollable conversation history showing user and agent messages.

What time is my next meeting?

You have a 1:1 with Sarah at 3:30 PM.

TSX
<AgentConversation />

Props:

Prop Type Default Description
className string — CSS class for the container.
itemClassName string — CSS class applied to each message.
renderMessage (entry: ConversationEntry) => ReactNode — Custom render function for messages.
emptyState ReactNode — Content shown when conversation is empty.
autoScroll boolean true Scroll to latest message automatically.
TSX
<AgentConversation
  emptyState={<p>Say something to start the conversation.</p>}
  renderMessage={(entry) => (
    <div className={entry.role === "user" ? "user-msg" : "agent-msg"}>
      {entry.content}
    </div>
  )}
/>

Data attributes: data-agent-conversation on the container, data-role="user" or data-role="assistant" on each message.

Lightweight markdown renderer for agent text. Handles bold, italic, inline code, code blocks, lists, headings, links, and horizontal rules. Supports streaming — update the children string as tokens arrive.

Voice agents combine speech-to-text, an LLM, and text-to-speech in a single connection.

  • Low-latency conversation
  • Natural prosody
TSX
<Response>{markdownString}</Response>

Props:

Prop Type Default Description
children string — Markdown string to render.
className string — Additional CSS class.

Data attributes: data-agent-response.

Text input field for sending messages to the agent. Submits on Enter (Shift+Enter for newline).

TSX
<AgentTextInput />

Props:

Prop Type Default Description
className string — Additional CSS class.
placeholder string "Type a message..." Input placeholder text.
disabled boolean false Disable the input.
onSend (text: string) => void — Callback when a message is sent.
submitButton ReactNode — Custom send button element.

Data attributes: data-agent-text-input.

Connect/disconnect toggle button. Reflects the current session state automatically.

TSX
<AgentStartButton />

Props:

Prop Type Default Description
className string — Additional CSS class.
startLabel ReactNode "Start" Label when idle.
connectingLabel ReactNode "Connecting..." Label while connecting.
stopLabel ReactNode "Stop" Label when connected.
reconnectingLabel ReactNode "Reconnecting..." Label while reconnecting.
onClick () => void — Optional click handler override.

Data attributes: data-agent-start-button, data-state (current state value).

Microphone mute/unmute toggle. Renders SVG mic icons by default.

TSX
<AgentMicrophoneButton />

Props:

Prop Type Default Description
className string — Additional CSS class.
activeLabel ReactNode Mic icon Content when microphone is active.
mutedLabel ReactNode Mic-off icon Content when muted.
disabledLabel ReactNode — Content when microphone is unavailable. Returns null if omitted.
onClick () => void — Optional click handler override.

Data attributes: data-agent-mic-button, data-state ("active", "muted", "inactive", or "disabled").

Speaker mute/unmute toggle. Renders SVG speaker icons by default.

TSX
<AgentSpeakerButton />

Props:

Prop Type Default Description
className string — Additional CSS class.
activeLabel ReactNode Speaker icon Content when speaker is active.
mutedLabel ReactNode Speaker-off icon Content when muted.
onClick () => void — Optional click handler override.

Data attributes: data-agent-speaker-button, data-state ("active" or "muted").

All-in-one button that combines connection and mode state into a single control. The appearance changes across five lifecycle states: idle, connecting, listening, speaking, and error.

TSX
<VoiceButton />

Props:

Prop Type Default Description
className string — Additional CSS class.
labels Partial<Record<VoiceButtonState, ReactNode>> See below Text for each state.
onClick () => void — Optional click handler override.

Default labels: "Start conversation", "Connecting...", "Listening...", "Agent speaking", "Error".

Style each state with the data-voice-state attribute:

CSS
[data-voice-state="listening"] {
  border-color: var(--dg-va-primary);
}
[data-voice-state="speaking"] {
  background: var(--dg-va-primary);
  animation: pulse 1.5s infinite;
}

Data attributes: data-agent-voice-button, data-voice-state ("idle", "connecting", "listening", "speaking", "error").

Deepgram’s animated hoop visualization. Canvas 2D rendering of four crescent arcs with gradient colors — lightweight and works everywhere without WebGL. Audio-reactive: the orb responds to actual microphone input and agent playback volume in real time.

Three visual states:

  • idle — deflated crescent, slow rocking, minimal animation
  • listening — full circle, gentle pulse, mic-reactive radius flutter
  • talking — crescent mouth, fast rotation, volume-modulated mouth movement
TSX
<Orb size={200} />

Props:

Prop Type Default Description
size number 200 Diameter in pixels.
colors [string, string] Deepgram greens Two gradient colors.
state "idle" | "listening" | "talking" "idle" Visual state.
getInputVolume () => number — Getter sampled per frame for mic volume (0—1).
getOutputVolume () => number — Getter sampled per frame for output volume (0—1).
inputVolume number — Direct mic volume value (0—1) for manual control.
outputVolume number — Direct output volume value (0—1) for manual control.
className string — Additional CSS class.

Automatic mode (default inside AgentProvider):

TSX
<Orb />

The orb reads getInputVolume() and getOutputVolume() every animation frame with zero re-renders.

Manual mode — push volume values directly:

TSX
<Orb inputVolume={0.5} outputVolume={0.3} state="talking" />

Custom volume sources:

TSX
<Orb
  getInputVolume={myMicAnalyser}
  getOutputVolume={myPlayerAnalyser}
/>

Custom colors:

TSX
<Orb colors={["#6366f1", "#ec4899"]} />

Data attributes: data-agent-orb, data-orb-state ("idle", "listening", "talking").

Real-time frequency bar visualization. Renders vertical bars on a canvas that react to audio input or output.

TSX
<BarVisualizer source="output" barCount={16} />

Props:

Prop Type Default Description
source "input" | "output" "output" Microphone or agent audio.
barCount number 16 Number of frequency bars.
className string — Additional CSS class.

Data attributes: data-agent-bar-visualizer.

Smooth oscillating waveform driven by a volume source. Blends two sine waves for an organic feel.

TSX
import { useAgentMicrophone } from "@deepgram/ui";
function MyWaveform() {
  const { getInputVolume } = useAgentMicrophone();
  return <LiveWaveform getVolume={getInputVolume} />;
}

Props:

Prop Type Default Description
getVolume (() => number) | (() => number)[] — Volume source(s) returning 0—1. When multiple are provided, the max value is used per frame.
active boolean true Whether the waveform animates. Renders a flat line when false.
color string --dg-va-primary Line color.
lineWidth number 2 Stroke width in pixels.
className string — Additional CSS class.

Data attributes: data-agent-live-waveform.

Dropdown for selecting the audio input device. Enumerates available microphones, requests permission on first open, and updates automatically when devices are plugged in or removed.

TSX
const [deviceId, setDeviceId] = useState("");
<MicSelector value={deviceId} onValueChange={setDeviceId} />

Props:

Prop Type Default Description
value string — Currently selected device ID (controlled).
onValueChange (deviceId: string) => void — Callback when the user selects a device.
className string — Additional CSS class.
disabled boolean false Disable the selector.

Data attributes: data-agent-mic-selector.

All components use CSS custom properties scoped to [data-dg-agent]. Add this attribute to your container element to apply the theme. Because these are standard CSS custom properties, they work with any CSS framework — Tailwind, CSS Modules, or plain stylesheets.

TSX
<div data-dg-agent>
  <AgentConversation />
  <AgentTextInput />
</div>

Tokens follow the shadcn --color-* naming convention generated by Tailwind v4’s @theme. The package ships sensible light defaults; dark values are applied automatically when [data-dg-scheme="dark"] is set or when the user’s system prefers dark mode. Override any token on a [data-dg-agent] ancestor to retheme.

CSS
[data-dg-agent] {
  /* Brand */
  --color-primary:            #13ef93;
  --color-primary-foreground: #000000;
  /* Surfaces */
  --color-background:            #ffffff;
  --color-foreground:            #111827;
  --color-card:                  #f3f4f6;
  --color-card-foreground:       #111827;
  --color-popover:               #ffffff;
  --color-popover-foreground:    #111827;
  --color-muted:                 #f3f4f6;
  --color-muted-foreground:      #6b7280;
  --color-accent:                #f9fafb;
  --color-accent-foreground:     #111827;
  --color-input:                 #f3f4f6;
  --color-border:                rgba(0, 0, 0, 0.1);
  --color-ring:                  #13ef93;
  --color-secondary:             #f3f4f6;
  --color-secondary-foreground:  #111827;
  --color-destructive:           #dc2626;
  --color-destructive-foreground:#ffffff;
  /* Typography & shape */
  --font-sans: system-ui, -apple-system, sans-serif;
  --radius:    1rem;
  /* Widget layout (panel + FAB sizing) */
  --dg-va-panel-w:  min(440px, 100vw);
  --dg-va-fab-size: 56px;
  --dg-va-padding:  16px;
  /* Derived from --color-primary by default — override only if you need a different relationship */
  --primary-hover:   color-mix(in srgb, var(--color-primary) 85%, #000);
  --primary-active:  color-mix(in srgb, var(--color-primary) 70%, #000);
  --msg-user-bg:     color-mix(in srgb, var(--color-primary) 12%, transparent);
  --msg-user-border: color-mix(in srgb, var(--color-primary) 30%, transparent);
}

Light/dark switching is driven by the data-dg-scheme attribute on the same element that has data-dg-agent. Without an explicit value, the components follow the user’s prefers-color-scheme.

TSX
<div data-dg-agent data-dg-scheme="dark">
  {/* Always renders in dark mode */}
</div>
Behaviour Selector
Force dark [data-dg-agent][data-dg-scheme="dark"]
Force light [data-dg-agent][data-dg-scheme="light"]
Follow system (default) no attribute, prefers-color-scheme: dark triggers dark

If your app uses Tailwind’s dark: variant or next-themes, write a small effect that mirrors that state onto data-dg-scheme. The package does not infer it from a .dark ancestor class.

A teal-on-midnight palette called Aurora, applied entirely through CSS custom properties on the host element. Same components, completely different feel.

CSS
[data-dg-agent].aurora-theme {
  /* Brand */
  --color-primary:              #5eead4;
  --color-primary-foreground:   #042f2e;
  --color-ring:                 #5eead4;
  /* Surfaces */
  --color-background:           #0a0e1a;
  --color-foreground:           #e6edf6;
  --color-card:                 #121829;
  --color-card-foreground:      #e6edf6;
  --color-popover:              #121829;
  --color-popover-foreground:   #e6edf6;
  --color-muted:                #1a2236;
  --color-muted-foreground:     #94a3b8;
  --color-accent:               #182238;
  --color-accent-foreground:    #5eead4;
  --color-input:                #0d1322;
  --color-border:               rgba(94, 234, 212, 0.14);
  --color-secondary:            #1a2236;
  --color-secondary-foreground: #5eead4;
  /* Derived (override the color-mix defaults for a softer glow) */
  --primary-hover:              #2dd4bf;
  --primary-active:             #14b8a6;
  --msg-user-bg:                rgba(94, 234, 212, 0.10);
  --msg-user-border:            rgba(94, 234, 212, 0.28);
  /* Slightly tighter corners than the default 1rem */
  --radius:                     14px;
}

Apply the class to your [data-dg-agent] container (or extend the override to the element itself) and every component inside picks up the new palette. The same pattern works for any palette — swap the values, keep the keys.

Components use data-agent-* attribute selectors instead of class names. This prevents collisions with your application’s CSS framework — no specificity battles with Tailwind utilities or CSS Modules hashes.

CSS
/* Target the conversation container */
[data-agent-conversation] {
  max-height: 400px;
}
/* Target user messages */
[data-agent-conversation] [data-role="user"] {
  text-align: right;
}
/* Target agent messages */
[data-agent-conversation] [data-role="assistant"] {
  font-style: italic;
}
/* Target the text input */
[data-agent-text-input] {
  font-size: 16px;
}
/* Target the orb by state */
[data-agent-orb][data-orb-state="talking"] {
  filter: brightness(1.2);
}
Component Attribute Values
Container data-dg-agent —
Color scheme data-dg-scheme "light", "dark"
AgentStatus data-agent-status, data-state "idle", "connecting", "connected", "reconnecting", "disconnected"
AgentConversation data-agent-conversation —
Messages data-role "user", "assistant"
AgentTextInput data-agent-text-input —
AgentStartButton data-agent-start-button, data-state "idle", "connecting", "connected", "reconnecting", "disconnected"
AgentMicrophoneButton data-agent-mic-button, data-state "active", "muted", "inactive", "disabled"
AgentSpeakerButton data-agent-speaker-button, data-state "active", "muted"
VoiceButton data-agent-voice-button, data-voice-state "idle", "connecting", "listening", "speaking", "error"
Orb data-agent-orb, data-orb-state "idle", "listening", "talking"
BarVisualizer data-agent-bar-visualizer —
LiveWaveform data-agent-live-waveform —
MicSelector data-agent-mic-selector —
Response data-agent-response —
Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu