Preview Link Card

A link that shows a screenshot of the page it leads to when hovered, in a card that links there too. Built on reka-ui's Hover Card.

<script setup lang="ts">
import {
  PreviewLinkCard,
  PreviewLinkCardContent,
  PreviewLinkCardImage,
  PreviewLinkCardPortal,
  PreviewLinkCardTrigger,
} from '@animate-ui/vue/primitives/reka-ui'

withDefaults(
  defineProps<{
    followCursor?: boolean | 'x' | 'y'
    href?: string
    side?: 'top' | 'right' | 'bottom' | 'left'
    sideOffset?: number
    align?: 'start' | 'center' | 'end'
    alignOffset?: number
  }>(),
  {
    followCursor: false,
    href: 'https://animate-ui.com/docs',
    side: 'top',
    sideOffset: 4,
    align: 'center',
    alignOffset: 0,
  },
)
</script>

<template>
  <p class="text-muted-foreground">
    Read the
    <PreviewLinkCard :href="href" :follow-cursor="followCursor">
      <PreviewLinkCardTrigger target="_blank" class="text-foreground underline">
        Animate UI Docs
      </PreviewLinkCardTrigger>
      <PreviewLinkCardPortal>
        <PreviewLinkCardContent
          :side="side"
          :side-offset="Number(sideOffset)"
          :align="align"
          :align-offset="Number(alignOffset)"
          target="_blank"
          class="ring-foreground/10 bg-popover z-50 origin-(--reka-hover-card-content-transform-origin) overflow-hidden rounded-lg shadow-md ring-1 outline-hidden"
        >
          <PreviewLinkCardImage alt="Animate UI Docs" class="block" />
        </PreviewLinkCardContent>
      </PreviewLinkCardPortal>
    </PreviewLinkCard>
    — hover to preview, click to dive in.
  </p>
</template>

Installation

npm install @animate-ui/vue motion-v
pnpm add @animate-ui/vue motion-v
yarn add @animate-ui/vue motion-v
bun add @animate-ui/vue motion-v

It's built on reka-ui's Hover Card, a peer dependency of this primitive:

npm install reka-ui
pnpm add reka-ui
yarn add reka-ui
bun add reka-ui

Usage

<script setup lang="ts">
import {
  PreviewLinkCard,
  PreviewLinkCardContent,
  PreviewLinkCardImage,
  PreviewLinkCardPortal,
  PreviewLinkCardTrigger,
} from '@animate-ui/vue/primitives/reka-ui';
</script>

<template>
  <PreviewLinkCard href="https://animate-ui.com/docs">
    <PreviewLinkCardTrigger>Animate UI Docs</PreviewLinkCardTrigger>
    <PreviewLinkCardPortal>
      <PreviewLinkCardContent>
        <PreviewLinkCardImage alt="Animate UI Docs" />
      </PreviewLinkCardContent>
    </PreviewLinkCardPortal>
  </PreviewLinkCard>
</template>

The screenshot comes from Microlink's API: it captures href on a mobile viewport three times the image's size. Pass src to show an image of your own instead. Either way, it's preloaded (a <link rel="preload"> in the head) as soon as the card mounts, so it's there when the card opens.

Animation

It is Animate UI's Hover Card, so the card moves exactly like it:

  • Content grows from 0.8 and fades in, from the trigger (--reka-hover-card-content-transform-origin), on a spring (stiffness 400, damping 29) that overshoots a little before it settles.
  • It opens after reka-ui's open-delay (700ms by default) and, once its close-delay is over (300ms), closes the same way: it shrinks back to 0.8 on the same spring while it fades out, then unmounts.
  • Reopening while it closes picks up from where it is, on the same spring.
  • reka-ui only opens it for mouse-like pointers: a tap on a touch screen follows the link, nothing sticks.
  • With follow-cursor on the Root, the card leans towards the pointer while it moves over the trigger, on a spring (stiffness 200, damping 17).
  • Under reduced motion, it only fades (no scale).

API Reference

The parts take the props of Animate UI's Hover Card, so those of reka-ui's Hover Card, plus the ones below.

PreviewLinkCard

Hover Card's Root (open-delay, close-delay, open, follow-cursor…), plus:

PropTypeDefault
href
string-
src?
string-
width?
number240
height?
number135
device-scale-factor?
number1
color-scheme?
'light' | 'dark''light'

PreviewLinkCardTrigger

Hover Card's Trigger: a link, to the Root's href unless it has its own.

PreviewLinkCardPortal, PreviewLinkCardArrow

Hover Card's Portal and Arrow.

PreviewLinkCardContent

Hover Card's Content (transition, exit-transition, side, align…), rendered as a link to the Root's href: it is the card, and its class styles it. With as-child, your element is rendered instead.

PropTypeDefault
side?
'top' | 'right' | 'bottom' | 'left''top'
side-offset?
number10
align?
'start' | 'center' | 'end''center'
href?
string-
target, rel, download, hreflang, ping, referrerpolicy?
string-

PreviewLinkCardImage

PropTypeDefault
alt?
string'preview image'
...props?
ImgHTMLAttributes-

usePreviewLinkCard

Returns getters for the card's href, its image's src, width and height: for an image of your own.

Credits

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/23/2026