Cited Answer
A streaming AI answer with inline citation chips, quote cards with verification, a linked source list and actions.
Overview
Write the answer with [1]-style markers and pass the sources. Each marker becomes a numbered chip that pops in as the text streams; hovering or focusing it opens a card with the site, the page title, the supporting quote, and whether that quote was verified on the page.
Below the answer, the sources it actually cited form a compact grid that lights up with the chip you’re on (and the other way round). When streaming ends, copy, thumbs up/down and regenerate fade in; copy draws a tick in place of the icon.
Text is rendered as text, never HTML, so model output can’t inject markup.
When to use
- Answers grounded in documents or web results (RAG, search assistants).
- Anywhere people need to check where a claim came from.
When not to use
- Showing the research process: use Web Search.
- Plain chat with no sources: use AI Composer.
Installation
pnpm dlx shadcn@latest add https://sundaeui.dev/r/cited-answer.jsonnpx shadcn@latest add https://sundaeui.dev/r/cited-answer.jsonyarn dlx shadcn@latest add https://sundaeui.dev/r/cited-answer.jsonbunx --bun shadcn@latest add https://sundaeui.dev/r/cited-answer.jsonWorks in any React project. Files are written to components/sundae/. Read the source in the stage’s Code view. Pro assets need a personal token. See authenticated installs.
- No dependencies beyond React 18 or later.
- Copy cited-answer.tsx and cited-answer.css into components/sundae/.
- The CSS file is imported by the component, so no extra configuration is needed.
- Import the component and use it as shown below.
Usage
import { CitedAnswer } from '@/components/sundae/cited-answer'
<CitedAnswer
text={answer} // "…announced politely [1]. Cancel the reader [3][4]."
streaming={isStreaming}
citations={[
{ id: 1, title: 'ARIA live regions', url: 'https://developer.mozilla.org/…', quote: 'Polite: updates are announced…', verified: true },
]}
onRegenerate={regenerate}
onFeedback={(v) => track('answer_feedback', v)}
/>Props
| Prop | Type | Default |
|---|---|---|
text*Answer with [n] markers; blank lines separate paragraphs. Rendered as plain text. | string | — |
citations*{ id, title, url, quote?, verified? }. Only cited ones appear in the list. | Citation[] | — |
streamingShows a caret and holds back the actions. | boolean | false |
onCopy / onRegenerate / onFeedbackCopy copies the text without markers. onFeedback gets "up" or "down". | functions | — |
themeauto follows a .dark ancestor. | 'auto' | 'light' | 'dark' | 'auto' |
Accessibility
- Citation chips are buttons labelled with the source title; their card is a tooltip linked with aria-describedby, opened on focus as well as hover, closed with Escape.
- The answer is aria-busy while streaming; copying is announced through a polite region.
- Feedback buttons use aria-pressed.
Customization
- Custom properties on .sd-ca: --ca-hot (active chip and quote rule), --ca-ok (verified), --ca-chip, --ca-card.
FAQ
- Is Cited Answer free?
- Cited Answer is part of Sundae Pro. The live preview is open to everyone; the source installs with a Pro account.
- How do I install Cited Answer?
- Run npx shadcn@latest add https://sundaeui.dev/r/cited-answer.json. The files are written to components/sundae/. It has no dependencies beyond React 18 or later.
- Does Cited Answer support keyboard and screen readers?
- Citation chips are buttons labelled with the source title; their card is a tooltip linked with aria-describedby, opened on focus as well as hover, closed with Escape. The answer is aria-busy while streaming; copying is announced through a polite region.
- Does Cited Answer respect reduced motion?
- Yes. With prefers-reduced-motion set, decorative motion is removed and state changes are instant.
More like this
All components →- Pro
Web Search
Components · Refined - Pro
Reasoning Trace
Components · Refined - Pro
Composer Attachments
Components · Refined Agent Thinking
Components · Refined- Pro
AI Composer
Components · Understated - Pro
Tool Call
Components · Refined