Docs askPro
The Ask panel for a docs site: answers scoped to the page, numbered citations that jump to the heading they used, questions about a selected passage, and a plain not in these docs state.
On this page
Installation
Usage
import { DocsAsk, DocsAskSelection } from "@/components/ui/chatcn/pro/docs-ask"
<DocsAskSelection target={articleRef} onAsk={setQuote} />
<DocsAsk
page="Webhooks"
messages={chat.chatcnMessages}
status={chat.status}
onSend={(text, { scope, quote }) => chat.sendMessage({ text }, { body: { scope, quote } })}
onStop={chat.stop}
quote={quote}
onQuoteChange={setQuote}
suggestions={["How do I verify a signature?"]}
/>Answers come from this page by default; the segmented control widens them to all docs. Citations are source-url parts and [1] in the text points at the first one. They render as small numbered chips on the text baseline and as a numbered list under the answer; a url that starts with # is a heading on this page, and clicking it scrolls there and marks the heading with data-docs-ask-target for 1.6 s. DocsAskSelection adds Ask about this next to any selection in your article and hands back the passage with the heading it sits under, which shows as a quote in the composer and above the question in the thread. When the docs do not cover a question, reply with a data-docs-not-found part: the panel says so plainly, with nothing to cite, and offers to search all docs plus your own notFoundActions.
Examples
States
Props
| Prop | Type | Notes |
|---|---|---|
messages | ChatcnMessage[] | The thread. Pass useChatcnChat().chatcnMessages |
status | "ready" | "submitted" | "streaming" | "error" | Same as AI SDK useChat |
error | ReactNode | Shown with a retry. Say how to fix it |
onSend | (text, { scope, quote? }) => void | Send with the scope and the quoted passage |
onStop, onRetry | () => void | |
page, sections | string, { id, title }[] | The page being read and its headings |
scope, defaultScope, onScopeChange | "page" | "all" | Default page |
quote, onQuoteChange | { text, sectionId?, sectionTitle? } | null | From DocsAskSelection |
suggestions, followUps | string[] | Starters while empty; questions under the answer |
onNavigate | (href) => void | Defaults to scrolling to the heading and marking it |
notFoundActions | ReactNode | A forum or support link in the not found state |
value, defaultValue, onValueChange | string | The input, controlled or not |
disabled | boolean | |
labels | Partial<DocsAskLabels> | Every string, for translation |
Keyboard
| Key | Action |
|---|---|
| Enter | Send. Shift Enter for a new line |
| Tab from a selection | Moves into Ask about this; Escape hands focus back to the text |
| Left and Right | Switch between This page and All docs |
Accessibility
- The thread is a labelled log; each citation chip is named Source n with its title.
- Following a citation moves focus to the heading, so screen readers land where the eye does.
- The scope switch is a radio group in a fieldset.
- The not found state is text with an icon, never color alone.
Motion
The scope switch moves its fill in 150 ms. Citations scroll smoothly to their heading, instantly under reduced motion. The answer streams with no per word effects.