The Gallery component displays images in a responsive grid layout with PhotoSwipe lightbox functionality. It works the same way in .astro files and MDX content — no import.meta.glob needed in your own page or content file.
Key Features
- 📸 PhotoSwipe Integration — full-screen lightbox with zoom, pan, and swipe gestures
- 🔄 Auto-loading — automatically discovers images in a
gallery/subfolder - 🔗 Shared galleries — reference one set of images by name from any page
- 📝 Custom Captions — via
captions.jsonor auto-generated from filenames - 🎨 Responsive Grid — configurable columns that adapt to screen size
- ⌨️ Keyboard Navigation — arrow keys, ESC, and full accessibility support
Live Examples
Default usage — colocated auto-loading
With no props, <Gallery /> loads images from a gallery/ folder next to the current page or content file, and captions from a captions.json in that same folder if present.
This demo loads from ./gallery/*.jpg and ./gallery/captions.json, both colocated with this doc page. (This page’s own file is docs/components/gallery/index.mdx — so the demo images end up at docs/components/gallery/gallery/. The doubled “gallery” is a coincidence of this page documenting the Gallery component itself; a normal article wouldn’t have this.)
import { Gallery } from '@lad-sapienza/scms-core/components/Gallery';
<Gallery />📄 View captions.json structure
Place this file in your gallery/ folder to provide custom captions:
{ "photo1.jpg": "A short caption for this image", "photo2.jpg": "Another caption"}Tip: keys can be filenames with or without extensions, and can use a different image resolution than the actual file — fuzzy matching strips resolution suffixes. Missing captions fall back to auto-generated ones from the filename. A malformed captions.json is ignored (with a console warning) rather than breaking the build.
Images by Pixabay
With reverse sorting
Images are sorted alphabetically by filename by default. Use reverseSorting to reverse this:
<Gallery reverseSorting={true} />Custom column configuration
Control the responsive grid by specifying minimum item width and maximum columns. The grid adapts between these values based on screen width:
<Gallery columns={{ min: 200, max: 3 }} />Shared gallery, referenced by name
A gallery that isn’t tied to one specific page — put it under src/galleries/<name>/ and reference it with the name prop from anywhere in the site. Useful for a set of images reused across multiple articles.
This demo loads from src/galleries/docs-demo/.
<Gallery name="docs-demo" />Explicit images (escape hatch)
For images that don’t live in a local gallery/ folder at all — remote URLs, a Directus-backed data source, a custom order computed at build time — pass an already-built GalleryImage[] array directly via images. This takes precedence over both auto-loading and name, and is the one case with no live demo here since it’s meant for data this docs site doesn’t have (e.g. a remote API).
<Gallery images={[ { src: '/photos/img1.jpg', thumb: '/photos/img1.jpg', width: 1200, height: 800, alt: 'Description', caption: 'My custom caption' }, ]}/>Folder Structure
Colocated (next to a page or content file):
my-post/ index.mdx ← or index.md, or a flat my-post.mdx gallery/ photo1.jpg photo2.jpg captions.json ← optionalShared (referenced by name from any page):
src/galleries/ scavi-2024/ photo1.jpg photo2.jpg captions.json ← optionalKnown limitation: colocated auto-loading matches the current page’s URL against the folder path on disk. If a content collection entry overrides its slug, or the site is deployed under a non-root base, that match can silently fail to find the folder. Use the name prop (shared galleries) or the explicit images prop as a workaround in that case.
Props API
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | — | Load a shared gallery from src/galleries/<name>/ |
images | GalleryImage[] | — | Explicit images — takes precedence over name and auto-loading |
reverseSorting | boolean | false | Reverse the default alphabetical sort |
columns | { min?: number, max?: number } | { min: 200, max: 1 } | min = minimum item width in px; max = maximum column count |
className | string | — | Additional CSS classes |
With no images and no name, the component auto-loads from a gallery/ folder colocated with the current page/content file.
GalleryImage Type
interface GalleryImage { src: string; // Full-size image URL thumb: string; // Thumbnail URL width: number; height: number; alt: string; caption?: string;}



