Gallery Lightbox Modal
A free React image lightbox modal with a native focus trap, keyboard navigation, captions and a thumbnail rail.
Customise
Code
<ModalLightboxGallery
images={[
{
id: "held-light",
src: "/held-light.jpg",
alt: "Abstract sun study in warm gradient tones",
caption: "Held Light No. 4",
width: 1600,
height: 1000,
},
{
id: "quiet-horizon",
src: "/quiet-horizon.jpg",
alt: "Minimal horizon line dividing two cool gradient tones",
caption: "Quiet Horizon",
width: 1600,
height: 900,
},
// ...two to twelve images total
]}
/>Gallery Lightbox Modal is a free React image lightbox for Next.js, built with Motion and Tailwind on top of the native dialog element. It renders its own grid of thumbnail buttons; activating one opens the lightbox at that exact image with a labelled dialog, a full focus trap and Escape to close, and closing returns focus to the exact thumbnail that opened it.
Previous and Next buttons, the arrow keys, and Home and End move cyclically through the collection, while a second thumbnail rail inside the dialog mirrors the same selection and scrolls its active item into view. A crossfade, scale or bounded slide plays between images inside a fixed-height stage, so switching images never shifts the surrounding layout, and only the two neighbouring images are preloaded once the lightbox opens. Every image carries meaningful alt text or an explicit decorative marking, an optional caption renders in a figcaption tied to the active figure, and with prefers-reduced-motion enabled every image swap is instant while the focus trap, keyboard navigation and captions keep working exactly as before.
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/modal-lightbox-galleryUsage
import { ModalLightboxGallery } from "@/components/modal-lightbox-gallery";
export default function Page() {
return (
<ModalLightboxGallery
images={[
{
id: "held-light",
src: "/held-light.jpg",
alt: "Abstract sun study in warm gradient tones",
caption: "Held Light No. 4",
width: 1600,
height: 1000,
},
{
id: "quiet-horizon",
src: "/quiet-horizon.jpg",
alt: "Minimal horizon line dividing two cool gradient tones",
caption: "Quiet Horizon",
width: 1600,
height: 900,
},
]}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| images | ReadonlyArray<{ id: string; src: string; alt: string; caption?: string; width: number; height: number }> | required | Two to twelve images with unique ids and stable dimensions. Malformed or duplicate entries are dropped rather than rendered broken. |
| initialId | string | undefined | Initially selected image. Falls back to the first valid id. |
| transitionStyle | "crossfade" | "slide" | "scale" | "crossfade" | Image-change treatment while the lightbox is open. |
| thumbnailPosition | "bottom" | "side" | "bottom" | Thumbnail rail placement on wide screens. Narrow screens always stack the rail below the image. |
| fit | "contain" | "cover" | "contain" | Media object-fit treatment for the active image. |
| backdropOpacity | number | 0.78 | Backdrop opacity, clamped to 0.45 through 0.92. |
| transitionDuration | number | 0.32 | Image transition duration in seconds, clamped to 0 through 0.7. |
| radius | number | 20 | Media and thumbnail corner radius in CSS pixels, clamped to 0 through 40. |
| className | string | undefined | Additional classes merged onto the gallery wrapper. |
Customisation
Gallery Lightbox Modal exposes three tokens: lightbox-accent tints the active thumbnail's ring and check badge, lightbox-panel backs the thumbnail rail plus the controls and caption (layered over an opaque background so they stay legible on any photograph), and lightbox-overlay colours the backdrop before backdropOpacity is applied. All three default to the shared semantic tokens, so retheme them from any ancestor without touching the component:
:root {
--lightbox-accent: var(--color-accent-400, var(--ring));
}
<ModalLightboxGallery
images={images}
transitionStyle="slide"
thumbnailPosition="side"
/>Frequently asked questions
- Is Gallery Lightbox Modal free for commercial use?
- Yes. Gallery Lightbox Modal is MIT licensed, so you can use it in personal and commercial projects without attribution.
- Is the lightbox accessible for keyboard and screen reader users?
- Yes. Activating a thumbnail opens a native dialog element with showModal, so the browser provides the focus trap, top layer rendering and Escape handling, and the page behind it becomes inert. The dialog has a labelled accessible name that updates with the active image, Close, Previous and Next are real buttons, background scroll is locked while open, and closing returns focus to the exact thumbnail that opened it. Malformed or empty image data is dropped safely rather than rendering a broken image or an unreachable focus target.
- How does the image transition work, and what happens with reduced motion?
- Motion animates only opacity, and for the slide style a bounded translate no larger than 32 pixels, inside a fixed-height stage so switching images never shifts the surrounding layout. Only the two images adjacent to the active one are preloaded after opening. With prefers-reduced-motion enabled every image swap is instant, with no slide, scale or crossfade travel, while the focus trap, arrow keys, captions and thumbnail selection all keep working exactly as before.