Skip to content
Template Empire
Browse components

Video Preview Cards

Free React video preview cards with accessible links and play controls, fine-pointer intent, muted media, and reduced-motion safety for Next.js.

  • White wildflower glowing against a deep green field, captioned The last of June

    Meadowgrass

    Wild carrot, cut hay and a green stem. Eau de parfum, blended once a year from a single June harvest.

  • Silhouette crossing a sunlit amber studio, captioned After six

    Amber Hours

    Labdanum, benzoin and a thread of smoke. The one people stop you about in lifts.

  • Layered leaves and a pale flower in soft blue evening light, captioned Under the fig

    Green Shade

    Fig leaf, vetiver and wet earth. The quietest of the three, and the one we wear most.

Customise

3
180ms
1.04
0.24s
4px
1.6
18px

Code

<VideoPreviewCards items={items} />

Video Preview Cards is a free video preview card component for React and Next.js, styled with Tailwind, that pairs complete linked content and meaningful posters with short, muted media previews. Each card keeps its title, description, destination and explicit Play control available before JavaScript runs, while the aspectRatio prop reserves the media geometry to prevent layout shift.

Qualified fine-pointer hover or keyboard focus can begin a preview after a configurable delay, but touch devices, manual mode and reduced-motion preferences always require the visible button. Starting another card pauses and resets the previous clip first, and previews are also stopped when the grid leaves the viewport, the document becomes hidden or the route unmounts.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/card-video-preview

Usage

import { VideoPreviewCards } from "@/components/ui/card-video-preview";

const items = [
  {
    id: "studio-film",
    title: "Studio film",
    description: "A compact motion study for the campaign.",
    href: "/work/studio-film",
    videoSrc: "/media/studio-film.mp4",
    posterSrc: "/media/studio-film-poster.jpg",
    posterAlt: "Performer crossing a warm, sunlit studio",
  },
  {
    id: "field-notes",
    title: "Field notes",
    description: "A quiet botanical sequence for the journal.",
    href: "/work/field-notes",
    videoSrc: "/media/field-notes.mp4",
    posterSrc: "/media/field-notes-poster.jpg",
    posterAlt: "White flower among deep green leaves",
  },
];

export default function Page() {
  return <VideoPreviewCards items={items} activation="intent" />;
}

Props

PropTypeDefaultDescription
itemsVideoPreviewItem[]requiredTwo to eight linked preview records with unique stable IDs, visible copy, video source and meaningful poster.
columns2 | 33Number of cards per row at the widest breakpoint.
activation"intent" | "manual""intent"Allows qualified fine-pointer hover or focus intent, or requires the explicit button for every preview.
previewDelaynumber180Delay before qualified intent starts playback, clamped from 0 to 600 milliseconds.
zoomnumber1.04Active video scale, clamped from 1 to 1.08 and disabled under reduced motion.
fadeDurationnumber0.24Poster-to-video opacity fade in seconds, clamped from 0.1 to 0.5 and capped at 0.15 under reduced motion.
hoverLiftnumber4Fine-pointer card lift in pixels, clamped from 0 to 8 and disabled under reduced motion.
aspectRationumber16 / 10Positive width divided by height ratio used to reserve every media frame.
radiusnumber18Card and media corner radius in pixels, clamped from 8 to 30.
classNamestringundefinedAdditional classes merged onto the responsive card grid.

Customisation

Use the scalar props to tune the preview effect and geometry without changing the card copy or media contract. Colours inherit the shared surface, background, border, ring, foreground and muted semantic tokens, so the cards follow the active light or dark theme automatically.

<VideoPreviewCards
  items={items}
  columns={2}
  activation="manual"
  previewDelay={240}
  zoom={1.02}
  fadeDuration={0.2}
  hoverLift={2}
  aspectRatio={4 / 3}
  radius={24}
/>

Frequently asked questions

Is Video Preview Cards free for commercial use?
Yes. Video Preview Cards is MIT licensed, so you can use it in personal and commercial projects without attribution.
Do the video preview cards work with touch and reduced motion?
Yes. Touch, coarse-pointer and reduced-motion contexts never start a preview from hover or focus. Every card keeps a visible 44 pixel Play button, and reduced motion removes zoom and lift while keeping any explicit poster fade at 150 milliseconds or less.
Can two card previews play at the same time?
No. Before a new video is asked to play, every other mounted video is synchronously paused and reset. Leaving the active card without focus, hiding the document, moving the grid offscreen or changing route also stops and resets playback.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates