Citations

Links an answer's claims to the sources behind them.

The View Transition API animates between two DOM states with a single call1. Same-document transitions shipped in Chrome 111, with cross-document support following later2, and Safari 18 added the single-document flavour3.

Installation

pnpm dlx shadcn@latest add @paneui/citations

Usage

Composition

Examples

Standalone Marker

File Sources

Open by Default

Streaming Sources

No Remote Favicons

List, Stack and Count

Use the parts on their own for custom layouts, like a sidebar.

Behaviour

Inside a CitationGroup, markers number themselves from the sources order. Clicking one opens the list, scrolls to the matching row and highlights it for 1.8s. The preview opens after delay (250ms) on hover or focus.

Favicons

By default CitationFavicon loads site icons from Google's favicon service when a source has a url (this sends the domain to Google), and falls back to the domain's first letter if that fails. The favicon prop works on the group and on Citations, CitationList, CitationStack and Citation. favicon={false} turns remote favicons off, favicon={(domain) => url} uses your own service, a source's faviconSrc sets its image directly, and icon replaces the image with your own node.

API Reference

Built on the Preview Card primitive. Only the props this library adds or changes are listed; everything else passes through.

CitationGroup

Provider linking inline markers to the reference list.

sources*
CitationSource[]
Sources, in citation order.
idPrefix
string
Prefix for row ids (anchor targets). Generated when omitted.
defaultOpen= false
boolean
Start with the reference list open.
open
boolean
Controlled open state of the list.
onOpenChange
(open: boolean) => void
Called when the list opens or closes.
favicon= true
boolean | ((domain: string) => string | undefined)
Favicon source for everything inside the group. true uses Google's service, false makes no remote request (monogram), and a function returns your own URL.
children*
ReactNode
The response containing markers and Citations.
PropTypeDefaultDescription
sources*CitationSource[]—Sources, in citation order.
idPrefixstring—Prefix for row ids (anchor targets). Generated when omitted.
defaultOpenbooleanfalseStart with the reference list open.
openboolean—Controlled open state of the list.
onOpenChange(open: boolean) => void—Called when the list opens or closes.
faviconboolean | ((domain: string) => string | undefined)trueFavicon source for everything inside the group. true uses Google's service, false makes no remote request (monogram), and a function returns your own URL.
children*ReactNode—The response containing markers and Citations.

Citation

Inline numbered marker with a hover preview. Also accepts every prop of PreviewCard.Trigger (a).

sourceId
string
Source id to resolve from the surrounding CitationGroup.
source
CitationSource
Explicit source, when not inside a group.
index
number
Explicit number; derived from the group order when omitted. Shows • when neither is known.
delay= 250
number
Hover delay in ms before the preview opens.
favicon
boolean | ((domain: string) => string | undefined)
Favicon source in the preview; defaults to the group's, then true.
PropTypeDefaultDescription
sourceIdstring—Source id to resolve from the surrounding CitationGroup.
sourceCitationSource—Explicit source, when not inside a group.
indexnumber—Explicit number; derived from the group order when omitted. Shows • when neither is known.
delaynumber250Hover delay in ms before the preview opens.
faviconboolean | ((domain: string) => string | undefined)—Favicon source in the preview; defaults to the group's, then true.
data-popup-open
Present while the preview is open (primary tint).
Data attributeDescription
data-popup-openPresent while the preview is open (primary tint).

Citations

Collapsible Sources summary with favicon stack and count. Renders nothing without sources. Also accepts every prop of Collapsible.

sources
CitationSource[]
Defaults to the group's sources.
title= "Sources"
ReactNode
Summary label.
open
boolean
Controlled open state; otherwise shared with the group.
defaultOpen= false
boolean
Initial state outside a group.
onOpenChange
(open: boolean) => void
Called when it opens or closes.
favicon
boolean | ((domain: string) => string | undefined)
Favicon source for the stack and list; defaults to the group's, then true.
className
string
Merged onto the root.
PropTypeDefaultDescription
sourcesCitationSource[]—Defaults to the group's sources.
titleReactNode"Sources"Summary label.
openboolean—Controlled open state; otherwise shared with the group.
defaultOpenbooleanfalseInitial state outside a group.
onOpenChange(open: boolean) => void—Called when it opens or closes.
faviconboolean | ((domain: string) => string | undefined)—Favicon source for the stack and list; defaults to the group's, then true.
classNamestring—Merged onto the root.

CitationList

Numbered reference rows (an <ol>); rows with a url are links, and without one the row and preview have no link.

sources
CitationSource[]
Defaults to the group's sources.
favicon
boolean | ((domain: string) => string | undefined)
Favicon source for the rows; defaults to the group's, then true.
className
string
Merged onto the list.
PropTypeDefaultDescription
sourcesCitationSource[]—Defaults to the group's sources.
faviconboolean | ((domain: string) => string | undefined)—Favicon source for the rows; defaults to the group's, then true.
classNamestring—Merged onto the list.
data-highlighted
On the row a marker just pointed to.
Data attributeDescription
data-highlightedOn the row a marker just pointed to.

CitationFavicon

Favicon chip; falls back to a monogram or icon.

source*
Pick<CitationSource, "url" | "domain" | "icon" | "faviconSrc">
Source to draw.
favicon= true
boolean | ((domain: string) => string | undefined)
true loads from Google's favicon service, false makes no remote request (monogram), a function maps the domain to your own URL. Defaults to the group's when inside one.
className
string
Merged onto the chip.
PropTypeDefaultDescription
source*Pick<CitationSource, "url" | "domain" | "icon" | "faviconSrc">—Source to draw.
faviconboolean | ((domain: string) => string | undefined)truetrue loads from Google's favicon service, false makes no remote request (monogram), a function maps the domain to your own URL. Defaults to the group's when inside one.
classNamestring—Merged onto the chip.

CitationStack

Overlapping favicons.

sources*
CitationSource[]
Sources to draw.
limit= 3
number
Max favicons shown.
favicon
boolean | ((domain: string) => string | undefined)
Favicon source; defaults to the group's, then true.
className
string
Merged onto the stack.
PropTypeDefaultDescription
sources*CitationSource[]—Sources to draw.
limitnumber3Max favicons shown.
faviconboolean | ((domain: string) => string | undefined)—Favicon source; defaults to the group's, then true.
classNamestring—Merged onto the stack.

CitationCount

Small "N sources" chip.

count*
number
Number of sources.
className
string
Merged onto the chip.
PropTypeDefaultDescription
count*number—Number of sources.
classNamestring—Merged onto the chip.

CitationSource

Shape of one source.

id*
string
Stable id used by sourceId.
title*
ReactNode
Source title.
url
string
Link target; also used for the favicon and domain.
domain
string
Display domain; derived from url when omitted.
snippet
ReactNode
Excerpt shown in the preview.
meta
ReactNode
Extra preview line, e.g. a publish date.
icon
ReactNode
Replaces the favicon.
faviconSrc
string
Explicit favicon URL (e.g. self-hosted); wins over the favicon option.
PropTypeDefaultDescription
id*string—Stable id used by sourceId.
title*ReactNode—Source title.
urlstring—Link target; also used for the favicon and domain.
domainstring—Display domain; derived from url when omitted.
snippetReactNode—Excerpt shown in the preview.
metaReactNode—Extra preview line, e.g. a publish date.
iconReactNode—Replaces the favicon.
faviconSrcstring—Explicit favicon URL (e.g. self-hosted); wins over the favicon option.