Search documentation

Search components and pages

Lightbox

A fullscreen image viewer with carousel navigation, zoom, and keyboard support.

Installation

Add the lightbox component with the shadcn CLI.

npx shadcn@latest add https://yami.ui.unsanity.ai/r/lightbox.json

Usage

import { Lightbox, LightboxContent, LightboxTrigger } from "@/components/ui/lightbox"

const images = [
  { src: "/photo-1.jpg", alt: "Mountain", caption: "Swiss Alps" },
  { src: "/photo-2.jpg", alt: "Forest",   caption: "Pacific NW" },
]

// Declarative — LightboxTrigger wraps any element
<Lightbox images={images}>
  <div className="flex gap-2">
    {images.map((img, i) => (
      <LightboxTrigger key={i} index={i}>
        <img src={img.src} alt={img.alt} className="size-20 object-cover rounded" />
      </LightboxTrigger>
    ))}
  </div>
  <LightboxContent />
</Lightbox>

Examples

useLightbox (imperative)

Open at a specific index programmatically

Code

"use client"
import { Lightbox, LightboxContent, useLightbox } from "@/components/ui/lightbox"

const images = [
  { src: "/photo-1.jpg", alt: "Mountain", caption: "Swiss Alps" },
  { src: "/photo-2.jpg", alt: "Forest",   caption: "Pacific NW" },
]

function Gallery() {
  const lb = useLightbox(images)
  return (
    <>
      <div className="grid grid-cols-3 gap-2">
        {images.map((img, i) => (
          <img
            key={i}
            src={img.src}
            alt={img.alt}
            onClick={() => lb.openAt(i)}
            className="cursor-pointer rounded object-cover"
          />
        ))}
      </div>
      <Lightbox {...lb.lightboxProps}>
        <LightboxContent />
      </Lightbox>
    </>
  )
}

LightboxTrigger (declarative)

Wrap any element to make it open the lightbox

Code

import { Lightbox, LightboxContent, LightboxTrigger } from "@/components/ui/lightbox"

<Lightbox images={images}>
  <div className="flex gap-2">
    {images.map((img, i) => (
      <LightboxTrigger key={i} index={i}>
        <img src={img.src} alt={img.alt} className="size-20 rounded object-cover" />
      </LightboxTrigger>
    ))}
  </div>
  <LightboxContent />
</Lightbox>