Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new

Inline Citation

An inline source citation that links supported text to source details.

Interactive preview

The shared preview uses React Base. The source below uses Base UI. Each example runs with local data.

Installation

Complete project setup with react/base, then install these components:

pnpm exec frontfriend download popover button -f react --primitive base

Press Enter or Space to open the source card. Its link is in the keyboard focus order. Escape closes the card and returns focus to its button. In an AI SDK adapter, use source-url parts, a stable sourceId, and the source title. Validate external source URLs before creating links.

Usage

Complete example

import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
export default function AiInlineCitationExample() {
  const sources = [
    {
      id: "docs",
      url: "https://frontfriend.dev/docs/",
      title: "Frontfriend documentation",
      description: "Install components and connect your Design System.",
      text: "Frontfriend components use the tokens from your Design System.",
    },
    {
      id: "theme",
      url: "https://www.w3.org/WAI/ARIA/apg/",
      title: "Accessible interaction patterns",
      description: "Use standard keyboard behavior and accessible names.",
      text: "Consistent keyboard behavior helps people use the application.",
    },
  ];
  return (
    <div
      style={{
        width: "100%",
        maxWidth: 560,
        minWidth: 0,
        marginInline: "auto",
        display: "grid",
        gap: 16,
        paddingBlock: 16,
        fontSize: "var(--text-sm)",
        lineHeight: 1.5,
      }}
    >
      {sources.map((source) => (
        <div key={source.id} style={{ lineHeight: 1.8 }}>
          {source.text}{" "}
          <Popover>
            <PopoverTrigger asChild>
              <Button
                variant="secondary"
                size="xs"
                aria-label={`${new URL(source.url).hostname}: ${source.title}`}
              >
                {new URL(source.url).hostname}
              </Button>
            </PopoverTrigger>
            <PopoverContent aria-label={source.title}>
              <div style={{ display: "grid", gap: 8 }}>
                <strong>{source.title}</strong>
                <p>{source.description}</p>
                <Button
                  variant="link"
                  nativeButton={false}
                  role="link"
                  render={
                    <a href={source.url} target="_blank" rel="noreferrer" />
                  }
                  style={{ justifySelf: "start" }}
                >
                  Read source (opens in a new tab)
                </Button>
              </div>
            </PopoverContent>
          </Popover>
        </div>
      ))}
    </div>
  );
}

Components and API

This composition has no separate component API. Use the APIs for its installed components.

ComponentTarget reference
popover Base UI API
button Base UI API