Components
Sources
Citations as numbered chips or cards, linked from [n] markers in the answer.
Example
Sources · 3
Interactive, and the same on the components page. Try the keyboard below on it.
Installation
npm i @dgesteves/agent-ui-kit aiimport { Sources, getSourceParts } from '@dgesteves/agent-ui-kit';
// Once per app (with Tailwind v4: @import '@dgesteves/agent-ui-kit/tailwind.css'; in your CSS)
import '@dgesteves/agent-ui-kit/styles.css';npx shadcn@latest add @agent-ui-kit/sourcesimport { Sources } from '@/components/agent-ui/sources';
import { getSourceParts } from '@/components/agent-ui/lib/ai';The styles are once per app; Getting started has the Tailwind v4 and plain CSS options.
Usage
// Send them from the server with toUIMessageStreamResponse({ sendSources: true }).
<Sources sources={getSourceParts(message.parts)} variant="cards" />API reference
Generated from the types the package ships, so it matches the version you install.
Sources
Citation list as compact chips or richer cards. External links open in a new tab.
Props
sourcesrequiredReadonlyArray<SourcePart | SourceItem>variant'chips' | 'cards'Default'chips'labelstring | nullDefault'Sources'Visible heading. Default "Sources"; pass
nullto hide it (it stays as the accessible name).idPrefixstringDefault'source'Prefix for element ids (
${idPrefix}-1, …) so inline citations can link to a source.
Other props go to the root <div>: className (merged with tailwind-merge), id, aria-*, data-* and event handlers.
SourceItem
A source in app-level shape. AI SDK source-url / source-document parts are accepted too.
idrequiredstringurlstringtitlestringdescriptionstringOptional snippet shown in the cards variant.
filenamestringFor documents.
mediaTypestring
Accessibility
- An ordered list named by
label("Sources"), not a landmark, so a long conversation doesn’t flood landmark navigation. - Links open in a new tab and say so to screen readers: "(opens in a new tab)".
- Each item has the id
${idPrefix}-${n}, which[n]citation links inMarkdownandAgentMessagepoint to. - It has no state and no
'use client', so it renders in Server Components too.
Theming
Every color, radius and font is a CSS variable, so the overrides in Theming apply, on :root or scoped to any element. These hooks are read from the component's markup.
- Slots (data-slot)
- sources
- State attributes
- data-varianton
sources'chips' | 'cards' - Tokens it uses
- --aui-accent-fg--aui-border--aui-border-strong--aui-fg--aui-fg-muted--aui-fg-subtle--aui-font-mono--aui-font-sans--aui-ring--aui-surface--aui-surface-2
/* Only this component, and only inside .settings-panel */
.settings-panel [data-slot='sources'] {
--aui-radius: 4px;
}
[data-slot='sources'][data-variant='chips'] {
outline: 1px solid var(--aui-accent);
}