Link preview
An unfurled link: a compact row or an expanded card with image, title and description, with a skeleton in the final layout and a plain-link fallback.
On this page
An expanded unfurl with an image and two compact rows.
Installation
Usage
import { LinkPreview } from "@/components/ui/chatcn/link-preview"
<LinkPreview
variant="expanded"
url="https://www.w3.org/WAI/ARIA/apg/patterns/treeview/"
title="Tree View Pattern | APG"
description="A tree view widget presents a hierarchical list."
image={og.image}
favicon={og.favicon}
/>Fetch the metadata on your server and pass it in. The component never fetches anything itself.
Examples
Loading, no image and error
The skeleton matches the final layout block for block, so the card does not resize when data lands. It is static: no shimmer, no pulse. When unfurling fails, the link stays a link.
Skeletons in the final layout, a card without an image and the plain link fallback.
Props
| Prop | Type | Notes |
|---|---|---|
url | string | Opens in a new tab with noopener noreferrer |
title, description | ReactNode | Without a title, the plain link renders |
siteName | ReactNode | Defaults to the domain |
favicon | string | Falls back to a globe |
image, imageAlt | string | Expanded only, at 1.91:1 |
state | "loading" | "ready" | "error" | Default ready |
variant | "compact" | "expanded" | Default compact |
Keyboard
| Key | Action |
|---|---|
Enter | Open the link in a new tab |
Accessibility
- The whole card is one link, so it is one tab stop with one name.
- Screen readers hear that it opens in a new tab. The arrow glyph is decorative.
- While loading, the link is
aria-busyand named after the domain.
Motion
- Hover changes the background and hairline over 150 ms, on fine pointers only. The card never lifts or scales.