- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Code Block
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Direction
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Questionnaire
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Tooltip
- Trace
- Typography
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)The last commit bumped a version in package.json without updating pnpm-lock.yaml, so the frozen install fails. Run pnpm install locally and commit the lockfile.
"use client"
import * as React from "react"Trace is a list of lines. Each line has an icon, a title, and an optional description and status. A line can expand to show more detail, link to a page, or open a dialog or sheet.
Every line has the same shape, so reasoning, tool calls, sources and plans built from Trace look and behave the same.
Use Trace for the steps an agent takes, like calling a tool, running a subagent or editing a file. Use Message for its reply, and Marker for notes and dividers between turns.
Built with Trace#
Every pattern below is a composition of Trace parts. See AI Elements for examples and code.
| Pattern | Shows |
|---|---|
| Chain of Thought | A summary that expands into the steps behind it. |
| Plan | The steps the agent plans to take, and how far it has got. |
| Queue | The agent's todo list, split into what is left and what is done. |
| Reasoning | The agent's thinking as it streams. |
| Sources | The links the agent used for a reply. |
| Stack Trace | A failed tool call and its stack frames. |
| Subagent | A subagent run, with its tool calls and result. |
| Task | The steps the agent takes, as it takes them. |
| Terminal | A command the agent runs, with its output as it streams. |
| Test Results | A test run by the agent, with its suites and failures. |
| Tool | A tool call the agent makes, from input to output. |
Installation#
pnpm dlx shadcn@latest add trace
Usage#
Use a TraceLine for a single step:
import { Trace, TraceIcon, TraceLine, TraceTitle } from "@/components/ui/trace"<Trace>
<TraceLine>
<TraceIcon>
<SearchIcon />
</TraceIcon>
<TraceTitle>Searched for minimumReleaseAge</TraceTitle>
</TraceLine>
</Trace>Wrap the line in a TraceCollapsible to show more detail when it expands:
import {
Trace,
TraceCollapsible,
TraceCollapsibleContent,
TraceCollapsibleTrigger,
TraceIcon,
TraceLine,
TraceTitle,
} from "@/components/ui/trace"<Trace>
<TraceCollapsible>
<TraceCollapsibleTrigger>
<TraceLine>
<TraceIcon>
<TerminalIcon />
</TraceIcon>
<TraceTitle>Ran node --version</TraceTitle>
</TraceLine>
</TraceCollapsibleTrigger>
<TraceCollapsibleContent>v24.18.0</TraceCollapsibleContent>
</TraceCollapsible>
</Trace>Composition#
Use the following composition to build a trace line:
Trace
└── TraceLine
├── TraceIcon
├── TraceTitle
├── TraceDescription
└── TraceIconWrap the line in a TraceCollapsible to show more detail when it expands:
Trace
└── TraceCollapsible
├── TraceCollapsibleTrigger
│ └── TraceLine
└── TraceCollapsibleContentTraceLine is always the line. To make a line do something, wrap it in that thing's trigger.
Features#
- One row for reasoning, tool calls, sources, plans and tasks
- Rows that expand, link out, or open a dialog, sheet, drawer or popover
running,errorandpendingstates, with a shimmer while running- Nested rows, so a summary expands into steps and a step into its output
- Works with reasoning, tool and source parts from the AI SDK
- Keyboard and screen reader support from the trigger that wraps each row
- Customizable styling through the
classNameprop on every part
Trace Line#
Use a TraceLine on its own for a step with no detail to show. It reads as plain text.
import { GitBranchIcon } from "lucide-react"
import {Status#
Set status on TraceLine when a step is running, has failed or hasn't started yet.
import {
CircleAlertIcon,
CircleCheckIcon,| Status | Use for |
|---|---|
| none | Work that is done: "Ran pnpm install". |
"error" | Work that failed. Say so in the title: "Failed to run pnpm lint". |
"running" | Work in progress. Write the title in the present tense: "Running pnpm build". |
"pending" | Work that has not started, such as a plan step: "Run pnpm test". |
Description#
Put secondary text such as a diff stat, a duration or a count in a TraceDescription after the TraceTitle. It does not truncate.
import { FilePenIcon, SearchIcon, TerminalIcon } from "lucide-react"
import {Collapsible#
Wrap the line in a TraceCollapsible to show more detail when it expands. Put the TraceLine inside TraceCollapsibleTrigger and the detail in TraceCollapsibleContent.
import { TerminalIcon } from "lucide-react"
import { CodeBlock, CodeBlockContent } from "@/components/ui/code-block"Open State#
Rows start closed. Use defaultOpen on TraceCollapsible to start open, or open with onOpenChange to control a row.
$ node --version
v24.18.0"use client"
import * as React from "react"To open a row while it streams and let the reader's click win, pass open ?? running.
const [open, setOpen] = React.useState<boolean>()
<TraceCollapsible
open={open ?? running}
onOpenChange={setOpen}
>
<TraceCollapsibleTrigger>
<TraceLine status={running ? "running" : undefined}>…</TraceLine>
</TraceCollapsibleTrigger>
<TraceCollapsibleContent>{text}</TraceCollapsibleContent>
</TraceCollapsible>Link#
Wrap the TraceLine in an anchor. For a new tab, use an arrow-up-right icon and sr-only "(opens in a new tab)".
import {
ArrowUpRightIcon,
ChevronRightIcon,<a href="https://docs.astro.build" target="_blank" rel="noreferrer">
<TraceLine>
<TraceTitle>
Install Astro
<span className="sr-only"> (opens in a new tab)</span>
</TraceTitle>
<TraceIcon>
<ArrowUpRightIcon />
</TraceIcon>
</TraceLine>
</a>Dialog#
Wrap the TraceLine in the dialog's trigger. The dialog owns its open state, Escape and focus return.
import { ArrowUpRightIcon, ChevronRightIcon, GlobeIcon } from "lucide-react"
import {<Dialog>
<DialogTrigger>
<TraceLine>
<TraceTitle>Searched the web for cache keys</TraceTitle>
<TraceIcon>
<ChevronRightIcon />
</TraceIcon>
</TraceLine>
</DialogTrigger>
<DialogContent>…</DialogContent>
</Dialog>Sheet#
The same shape as the dialog. Drawer and Popover work the same way.
import { ChevronRightIcon, FolderSearchIcon } from "lucide-react"
import {Group#
Put rows that sit next to each other in a Trace. It also styles any trigger or link that wraps a TraceLine.
import { FileTextIcon, SearchIcon, TerminalIcon } from "lucide-react"
import {Sources#
A collapsible row whose detail is a Trace of link rows.
import { ArrowUpRightIcon, GlobeIcon } from "lucide-react"
import {See Sources for more examples.
Chain of Thought#
A chain of thought is a collapsible row with step rows inside. Set the parent's status and title from its children.
import { ChevronRightIcon, FileTextIcon, SearchIcon } from "lucide-react"
import { Badge } from "@/components/ui/badge"See Chain of Thought and Task for more examples.
Commit#
A commit is a collapsible row with a line for each changed file. Say what changed in the title, Added, Edited or Deleted, and put the line counts in the description. Each file opens its diff in a Sheet.
import {
ChevronRightIcon,
FilePenIcon,Whole Turn#
Three levels: the turn, a summary, and the rows. Text between steps sits between two Trace lists.
Node is installed and pnpm is not. Reading the docs config.
import {
BrainIcon,
ChevronRightIcon,Reasoning#
Render a reasoning part from the AI SDK. The row is a TraceLine until the first text arrives. See Open State.
"use client"
import * as React from "react"See Reasoning for more examples.
Tool#
Render tool parts from the AI SDK. Map the tool part as in Tool.
"use client"
import * as React from "react"See Tool for more examples.
Accessibility#
Trace adds no roles of its own. Each line gets its semantics from the element that wraps it.
- A
TraceLineon its own is aspan. It is read as text and is not a tab stop. - Wrap it in a
TraceCollapsibleTriggerand it becomes a button witharia-expanded. Wrap it in a link, or in the trigger for a dialog or sheet, and it takes the keyboard and focus behavior of that element. TraceIconis hidden from assistive tech, soTraceTitleis the accessible name. Write it as a sentence that says what happened, like "Edited trace.tsx", not just "trace.tsx".- When a link opens a new tab, add "(opens in a new tab)" to the title with
sr-only. - Status is shown with color and motion, so put it in the title too. Write "Running pnpm build" while it runs and "Failed to run pnpm build" when it errors.
- The shimmer on a running title stops when the reader prefers reduced motion. The title still says what is happening.
- Inside a Message Scroller, each line is announced once when it is added.
TraceCollapsibleContentmutes its text. If you put a block with a muted background inside it, give the blocktext-foregroundso it keeps its contrast.CodeBlocksets its own text color.
API Reference#
Trace#
A list of rows. It also styles any trigger or link that wraps a TraceLine.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the list. |
TraceLine#
One line: an icon and a title. It is a span, so it is not a button or a tab stop. Wrap it in a trigger or a link to make it do something.
| Prop | Type | Default | Description |
|---|---|---|---|
status | "running" | "error" | "pending" | - | The state of the work the line reports. |
className | string | - | Additional classes to apply to the line. |
TraceIcon#
A decorative icon slot, hidden from assistive tech. Before the title it names the action; after it, it is the indicator.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the icon slot. |
TraceTitle#
One sentence on one line. It truncates and shimmers while the line is running.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the title. |
TraceDescription#
Secondary text after the title, such as a count or a duration. It does not truncate.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the description. |
TraceCollapsible#
A row that expands. It accepts the props of Collapsible.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | The controlled open state. Pass it with onOpenChange. |
defaultOpen | boolean | false | Whether the row starts open. |
onOpenChange | (open: boolean) => void | - | Called when the open state changes. |
className | string | - | Additional classes to apply to the row. |
TraceCollapsibleTrigger#
The button that opens and closes the row. Put a TraceLine inside it. It adds a chevron after the line.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the trigger. |
TraceCollapsibleContent#
The detail of a row that expands.
| Prop | Type | Default | Description |
|---|---|---|---|
keepMounted | boolean | false | Keep the detail mounted while closed, so nested rows keep their open state. |
className | string | - | Additional classes to apply to the content. |
On This Page
Built with TraceInstallationUsageCompositionFeaturesTrace LineStatusDescriptionCollapsibleOpen StateLinkDialogSheetGroupSourcesChain of ThoughtCommitWhole TurnReasoningToolAccessibilityAPI ReferenceTraceTraceLineTraceIconTraceTitleTraceDescriptionTraceCollapsibleTraceCollapsibleTriggerTraceCollapsibleContent