Lightbox Carousel
Astro image carousels that open the chosen slide in a larger view.






Image gallery
---
import { Image } from "astro:assets"
import {
LightboxCarousel,
LightboxCarouselContent,
LightboxCarouselItem,
LightboxCarouselNext,
LightboxCarouselPrevious,
} from "@/components/ui/lightbox-carousel"
const images = [
{
src: "https://images.unsplash.com/photo-1470770841072-f978cf4d019e?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "Mountains reflected in a lake",
},
{
src: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "Sunlight through forest trees",
},
{
src: "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "Open landscape in evening light",
},
{
src: "https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "A mountain peak above the clouds",
},
{
src: "https://images.unsplash.com/photo-1472396961693-142e6e269027?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "Deer in a green forest",
},
{
src: "https://images.unsplash.com/photo-1447752875215-b2761acb3c5d?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "A path through tall trees",
},
]
---
<div class="mx-auto w-full max-w-3xl px-14 py-4">
<LightboxCarousel>
<LightboxCarouselContent>
{images.map((image) => (
<LightboxCarouselItem alt={image.alt}>
<Image
slot="preview"
{...image}
alt=""
class="aspect-3/2 w-full object-cover"
loading="lazy"
/>
<Image slot="content" {...image} loading="lazy" />
</LightboxCarouselItem>
))}
</LightboxCarouselContent>
<LightboxCarouselPrevious />
<LightboxCarouselNext />
</LightboxCarousel>
</div>
Installation
bunx --bun shadcn@latest add @gnosticai/lightbox-carousel
The command also installs Lightbox and Carousel.
Usage
Compose the page carousel from the same parts as Carousel. Each item needs a
preview slot and a content slot. preview is the slide on the page.
content is the slide in the enlarged dialog. Click a slide to open that
image. Previous and Next in the dialog continue through the same list. Close
the dialog and the page carousel shows the slide you were viewing.
---
import { Image } from "astro:assets"
import {
LightboxCarousel,
LightboxCarouselContent,
LightboxCarouselItem,
LightboxCarouselNext,
LightboxCarouselPrevious,
} from "@/components/ui/lightbox-carousel"
import lake from "../assets/lake.jpg"
---
<LightboxCarousel>
<LightboxCarouselContent>
<LightboxCarouselItem alt="Mountains reflected in a lake">
<Image slot="preview" src={lake} alt="" class="aspect-3/2 w-full object-cover" />
<Image slot="content" src={lake} alt="Mountains reflected in a lake" />
</LightboxCarouselItem>
</LightboxCarouselContent>
<LightboxCarouselPrevious />
<LightboxCarouselNext />
</LightboxCarousel>
Arrow keys move the open carousel. Escape, the close button, and an overlay click close the dialog. The carousel loops.
Keep links and buttons out of preview. That slot is already inside a button.
Several slides
Set the item basis to show more than one slide. caption appears under the
enlarged image.




Landscape gallery
---
import { Image } from "astro:assets"
import {
LightboxCarousel,
LightboxCarouselContent,
LightboxCarouselItem,
LightboxCarouselNext,
LightboxCarouselPrevious,
} from "@/components/ui/lightbox-carousel"
const images = [
{
src: "https://images.unsplash.com/photo-1470770841072-f978cf4d019e?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "Mountains reflected in a lake",
caption: "A quiet mountain lake.",
},
{
src: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "Sunlight through forest trees",
caption: "Morning light between the trees.",
},
{
src: "https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "A mountain peak above the clouds",
caption: "The ridge stays above the cloud line.",
},
{
src: "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?w=1200&h=800&auto=format&fit=crop",
width: 1200,
height: 800,
alt: "Open landscape in evening light",
caption: "The valley holds the last light.",
},
]
---
<div class="mx-auto w-full max-w-3xl px-14 py-4">
<LightboxCarousel label="Landscape gallery">
<LightboxCarouselContent class="-ml-4">
{images.map(({ caption, ...image }, i) => (
<LightboxCarouselItem
alt={image.alt}
caption={caption}
class="basis-1/2 pl-4 @min-xl/carousel:basis-1/3"
>
<Image
slot="preview"
{...image}
alt={`Image ${i + 1}`}
class="aspect-3/2 w-full object-cover"
loading={i === 0 ? "eager" : "lazy"}
/>
<Image slot="content" {...image} loading="lazy" />
</LightboxCarouselItem>
))}
</LightboxCarouselContent>
<LightboxCarouselPrevious />
<LightboxCarouselNext />
</LightboxCarousel>
</div>
API
LightboxCarousel accepts native div attributes and these options:
| Prop | Type | Default | Purpose |
|---|---|---|---|
label |
string |
Image gallery |
Accessible name for the page carousel. |
LightboxCarouselContent accepts the same attributes as CarouselContent.
LightboxCarouselPrevious and LightboxCarouselNext accept the same
attributes as the carousel controls.
LightboxCarouselItem accepts native div attributes and these options:
| Prop | Type | Default | Purpose |
|---|---|---|---|
alt |
string |
Required | Slide button name and dialog title. |
caption |
string |
— | Optional text under the enlarged image. |
hoverZoom |
boolean |
true |
Scale the slide preview on hover with hover:scale-105. |
Both preview and content slots are required. The page carousel is one
slide wide unless you set basis on the item. Spacing follows Carousel:
pair a negative margin on LightboxCarouselContent with padding on each item.
When to use Lightbox Carousel
Compose the thumbnail carousel and lightbox parts around the same ordered images. Use stable image order so the enlarged view matches the selected thumbnail. Pass carousel options through the existing props.
Keyboard and behavior
Embla supplies slide movement and the dialog controller supplies modal focus. Keep labelled previous, next, and close controls. Check keyboard use in both the page carousel and the enlarged view.
Theme and layout
Use small thumbnail sources and suitable full-size images to limit transfer size. Check aspect ratios and captions at narrow widths. The component does not generate image derivatives or load a media library for you.
Related choices
Use Carousel without a modal or Lightbox Grid for a page of thumbnails.