Link Preview
Overlaysimport { LinkPreview } from "bits-ui" Profile hover card
A linked avatar reveals identity, location, repository, and star statistics on hover
<script lang="ts">
import { Avatar, LinkPreview } from 'bits-ui';
import { MapPin } from '@lucide/svelte';
</script>
<div class="flex items-center justify-center gap-2 text-sm text-ink-400">
<span>Built by</span>
<LinkPreview.Root openDelay={250} closeDelay={180}>
<LinkPreview.Trigger
href="https://github.com/sveltejs"
target="_blank"
rel="noreferrer noopener"
class="inline-flex items-center gap-2 rounded-md font-medium text-brand-400 outline-none hover:text-brand-500 focus-visible:ring-2 focus-visible:ring-brand-500"
>
<Avatar.Root class="size-7 overflow-hidden rounded-full bg-red-500/15 text-xs font-semibold text-red-200">
<Avatar.Image src="https://github.com/sveltejs.png" alt="Svelte organization" class="size-full object-cover" />
<Avatar.Fallback class="flex size-full items-center justify-center">SV</Avatar.Fallback>
</Avatar.Root>
@sveltejs
</LinkPreview.Trigger>
<LinkPreview.Portal>
<LinkPreview.Content
side="bottom"
align="start"
sideOffset={10}
class="panel animate-pop-in z-[100] w-80 p-5 text-ink-200 shadow-2xl outline-none"
>
<div class="flex items-start gap-3">
<Avatar.Root class="size-12 shrink-0 overflow-hidden rounded-full bg-red-500/15 font-semibold text-red-200">
<Avatar.Image src="https://github.com/sveltejs.png" alt="Svelte organization" class="size-full object-cover" />
<Avatar.Fallback class="flex size-full items-center justify-center">SV</Avatar.Fallback>
</Avatar.Root>
<div class="min-w-0">
<p class="font-semibold text-ink-50">Svelte</p>
<p class="text-xs text-ink-400">@sveltejs</p>
</div>
</div>
<p class="mt-3 text-sm leading-6 text-ink-300">
Cybernetically enhanced web apps: a compiler, application framework, and open-source community.
</p>
<div class="mt-4 flex items-center gap-4 border-t border-ink-800 pt-3 text-xs text-ink-400">
<span><strong class="text-ink-50">82</strong> repositories</span>
<span><strong class="text-ink-50">84k</strong> stars</span>
<span class="inline-flex items-center gap-1"><MapPin class="size-3.5" /> Global</span>
</div>
<LinkPreview.Arrow class="fill-ink-800" />
</LinkPreview.Content>
</LinkPreview.Portal>
</LinkPreview.Root>
</div>
Article preview
Short open and longer close delays make a text-link preview easy to approach
The migration guide explains why runes make reactivity explicit before touching a large component tree.
<script lang="ts">
import { LinkPreview } from 'bits-ui';
import { ArrowUpRight, Clock } from '@lucide/svelte';
</script>
<p class="mx-auto max-w-lg text-center text-sm leading-7 text-ink-400">
The migration guide explains why
<LinkPreview.Root openDelay={150} closeDelay={500}>
<LinkPreview.Trigger
href="https://svelte.dev/docs/svelte/v5-migration-guide"
target="_blank"
rel="noreferrer noopener"
class="font-medium text-brand-400 underline decoration-brand-500/40 underline-offset-4 outline-none hover:text-brand-500 focus-visible:ring-2 focus-visible:ring-brand-500"
>
runes make reactivity explicit
</LinkPreview.Trigger>
<LinkPreview.Portal>
<LinkPreview.Content
side="top"
align="center"
sideOffset={10}
class="panel animate-pop-in z-[100] w-80 overflow-hidden text-left shadow-2xl outline-none"
>
<div class="h-20 bg-gradient-to-br from-brand-600/50 via-ink-800 to-accent-500/30 p-4">
<span class="chip border-white/10 bg-ink-950/60 text-ink-200">svelte.dev</span>
</div>
<div class="p-4">
<div class="flex items-start justify-between gap-3">
<h3 class="text-sm font-semibold text-ink-50">Svelte 5 migration guide</h3>
<ArrowUpRight class="size-4 shrink-0 text-ink-400" />
</div>
<p class="mt-2 text-xs leading-5 text-ink-400">
A practical map from legacy syntax to runes, snippets, event properties, and the new component model.
</p>
<p class="mt-3 flex items-center gap-1.5 text-xs text-ink-600">
<Clock class="size-3.5" /> 12 minute read
</p>
</div>
<LinkPreview.Arrow class="fill-ink-800" />
</LinkPreview.Content>
</LinkPreview.Portal>
</LinkPreview.Root>
before touching a large component tree.
</p>
Link Preview is intentionally pointer-only: it ignores touch, and keyboard users follow the link
without receiving the preview. Never put vital or actionable information in the card. Use openDelay and closeDelay on Root; Floating UI positions Content, while ContentStatic opts out of that positioning entirely.
LinkPreview.Portal renders into document.body by default to avoid clipping
and stacking-context problems. Floating content exposes a focus trap plus cancellable open/close
focus hooks, but the intended hover-card pattern does not move focus into the preview. Escape and
outside pointer-down close the floating layer by default; their behavior props and callbacks live
on LinkPreview.Content.