# Link Preview

A rich Open-Graph preview card that turns a URL and its metadata into a themed, accessible link tile — no fetching required.

<p class="kai-tag-sub">kai-link-preview</p>

Turn a URL and its Open-Graph metadata into a rich, themed preview tile — assign one property and the card handles image, title, description, favicon, and domain with graceful fallbacks for anything missing.

## Preview

> **tip:** 
Use `<kai-link-preview>` when an AI agent surfaces a URL and you want a rich tile instead of a plain hyperlink. It fits inside a `<kai-cards>` stream or as a standalone card in a thread. If you only have the URL at render time, wire `configureLinkPreview` to your own OG-scraping backend — the card shows a skeleton while it waits.

## Usage

Set `data` in JavaScript (it's an object, not an attribute):

```html
<kai-link-preview id="lp"></kai-link-preview>

<script type="module">

  await customElements.whenDefined('kai-link-preview');

  const lp = document.getElementById('lp');
  lp.cardId = 'card-link-1';
  lp.data = {
    url: 'https://example.com/blog/generative-ui',
    title: 'Generative UI, explained',
    description: 'How agents render typed, themed cards in the chat.',
    image: 'https://example.com/og.png',
    favicon: 'https://example.com/favicon.ico',
    siteName: 'Example Blog',
    domain: 'example.com',
  };
</script>
```

- **`data`** — every key except `url` is optional.
- **`cardId`** — set as `card-id` attribute or `cardId` property; correlates emitted events when multiple cards are in a `<kai-cards>` host.
- **Pure by default** — the element never makes network calls. For bare `{ url }`, call `configureLinkPreview({ fetchMetadata })` once at startup to point at your backend.
- **Click** dispatches a bubbling `kai-card` CustomEvent with `{ kind: 'open', url, target: 'tab' }`. A missing or broken image hides the image region silently; an invalid `url` renders a non-clickable "Invalid link" chip.

## Examples

### Full Preview

All OG fields supplied — image, title, description, site name, domain, and favicon.

### No Image

When no `image` is provided the card degrades cleanly to the text-and-domain layout.

### Bare URL with Fetcher

Passing only `{ url }` — the card shows a skeleton until `configureLinkPreview` resolves metadata from your backend:

```ts

configureLinkPreview({
  fetchMetadata: (url) =>
    fetch('/api/og?url=' + encodeURIComponent(url)).then((r) => r.json()),
});
```

### Invalid Link

When `url` fails validation the card renders a non-clickable "Invalid link" chip and emits a single `error` event via the `kai-card` envelope.

## Props

## Composed from
