# Sources A component that allows a user to view the sources or citations used to generate a response. The `Sources` component allows a user to view the sources or citations used to generate a response. See `scripts/sources.tsx` for this example. ## Installation ```bash npx ai-elements@latest add sources ``` ## Usage with AI SDK Build a simple web search agent with Perplexity Sonar. Add the following component to your frontend: ```tsx title="app/page.tsx" "use client"; import { useChat } from "@ai-sdk/react"; import { Source, Sources, SourcesContent, SourcesTrigger, } from "@/components/ai-elements/sources"; import { PromptInput, type PromptInputMessage, PromptInputTextarea, PromptInputSubmit, } from "@/components/ai-elements/prompt-input"; import { Conversation, ConversationContent, ConversationScrollButton, } from "@/components/ai-elements/conversation"; import { Message, MessageContent, MessageResponse, } from "@/components/ai-elements/message"; import { useState } from "react"; import { DefaultChatTransport } from "ai"; const SourceDemo = () => { const [input, setInput] = useState(""); const { messages, sendMessage, status } = useChat({ transport: new DefaultChatTransport({ api: "/api/sources", }), }); const handleSubmit = (message: PromptInputMessage) => { if (message.text.trim()) { sendMessage({ text: message.text }); setInput(""); } }; return (
{messages.map((message) => (
{message.role === "assistant" && ( part.type === "source-url" ).length } /> {message.parts.map((part, i) => { switch (part.type) { case "source-url": return ( ); } })} )} {message.parts.map((part, i) => { switch (part.type) { case "text": return ( {part.text} ); default: return null; } })}
))}
setInput(e.currentTarget.value)} className="pr-12" />
); }; export default SourceDemo; ``` Add the following route to your backend: ```tsx title="api/chat/route.ts" import { convertToModelMessages, streamText, UIMessage } from "ai"; import { perplexity } from "@ai-sdk/perplexity"; // Allow streaming responses up to 30 seconds export const maxDuration = 30; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); const result = streamText({ model: "perplexity/sonar", system: "You are a helpful assistant. Keep your responses short (< 100 words) unless you are asked for more details. ALWAYS USE SEARCH.", messages: await convertToModelMessages(messages), }); return result.toUIMessageStreamResponse({ sendSources: true, }); } ``` ## Features - Collapsible component that allows a user to view the sources or citations used to generate a response - Customizable trigger and content components - Support for custom sources or citations - Responsive design with mobile-friendly controls - Clean, modern styling with customizable themes ## Examples ### Custom rendering See `scripts/sources-custom.tsx` for this example. ## Props ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the root div. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `count` | `number` | Required | The number of sources to display in the trigger. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the CollapsibleTrigger component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the content container. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.AnchorHTMLAttributes` | - | Any other props are spread to the anchor element. |