LocalMode /ui
Conversation

Sources

Collapsible local RAG citations with favicon/title/excerpt chips, a relevance score, and an optional tabbed layout.

Sources

The Sources primitives render retrieval citations from local RAG results (e.g. useSemanticSearch). Sources is the collapsible container; SourcesTrigger shows the count; each Source renders a favicon/title/excerpt chip and a 0–1 relevance score. An optional tabbed layout switches between Web / Images / News-style result variants. All favicons/images come from already-stored local metadata — there is no remote unfurl.

Preview

Installation

pnpm dlx shadcn@latest add @localmode/ui/conversation/sources
npx shadcn@latest add @localmode/ui/conversation/sources
yarn dlx shadcn@latest add @localmode/ui/conversation/sources
bunx --bun shadcn@latest add @localmode/ui/conversation/sources

Data source & dependencies

Data source: renders a list of { href, title } you pass — works with any backend. Recommended producer: useSemanticSearch from @localmode/react (on-device). See Use with the Vercel AI SDK.

  • clsx + tailwind-merge — via the shared cn() util (installed automatically as a registry dependency)

Files installed

  • sources.tsxSources, SourcesTrigger, SourcesContent, Source
  • lib/utils.ts — the cn() helper (if not already present)

Props

Source

Prop

Type

Examples

From local search results

import { Source, Sources, SourcesContent, SourcesTrigger } from '@/components/sources';

<Sources>
  <SourcesTrigger count={results.length} />
  <SourcesContent>
    {results.map((r) => (
      <Source key={r.id} source={{ id: r.id, title: r.metadata.title, excerpt: r.text, score: r.score }} />
    ))}
  </SourcesContent>
</Sources>

Customization

Enable the tabbed layout by passing tabbed + sources to SourcesContent. Favicons render from faviconUrl in your stored metadata — leave it unset for the default globe icon.

These primitives are presentational and hook-driven: they render props and emit callbacks, holding only local view state. The orchestration state (e.g. useSemanticSearch) lives in your app. Every surface uses shadcn/ui CSS-variable utilities, so it inherits your theme — restyle the copied file freely.

On this page