Filterable gallery with lightbox, fed straight from the media library.
A responsive image gallery the client curates from Studio: pick images from the media library, caption them, tag them, done. Visitors can filter by tag and open any image in a full-screen lightbox. Thumbnails are served resized — the page never ships full-resolution files.
The gallery is a page section: a repeatable list of images with captions and tags, defined in cms.config.js. The client composes it onto pages like any other section. The frontend renders a grid using the CMS's on-the-fly image resizing (?w= on any upload URL) and a dependency-free <dialog> lightbox.
You are adding a gallery section to a Prelo project. Read `prelo docs sections` and `prelo docs config` if unsure.
1. **Section definition.** In `cms.config.js` under `sections:`:
```js
gallery: {
fields: {
heading: { type: "text" },
layout: { type: "select", options: ["grid", "masonry"], studio: "variant" },
images: { type: "list", of: {
image: { type: "image", required: true },
alt: { type: "text", required: true },
caption: { type: "text" },
tag: { type: "text" },
}},
},
},
```
The generic Studio renders the list as a repeater with media-library pickers automatically — no Studio work.
2. **Renderer.** Add a `gallery` renderer wherever the project renders sections/blocks:
- One-process site: pass it in the `renderBody(body, { gallery: (block) => … })` renderer map.
- Next/Astro frontend: a `Gallery` component in the section-rendering switch.
3. **Grid.** Render an image grid (CSS grid for `grid`, CSS columns for `masonry`). Each thumb is an `<img>` with `src="{upload}?w=640"`, `srcset` at 480/640/960, `loading="lazy"`, the required `alt`, and the caption underneath in the project's muted text style.
4. **Tag filter.** Collect the distinct non-empty tags in the section; if there are 2+, render a row of filter buttons ("All" + each tag) above the grid. Filtering is client-side (hide/show, no relayout jank — keep grid items in the DOM and toggle a hidden class). Skip the row entirely when tags aren't used.
5. **Lightbox.** Use a native `<dialog>`: clicking a thumb opens the full image (`?w=1600`), caption below, prev/next buttons and arrow-key navigation across the *currently filtered* set, Escape and backdrop-click to close. Trap focus while open; restore focus to the opening thumb on close. No third-party library.
6. **Progressive enhancement.** Without JavaScript the grid must still render and each thumb link directly to the full-size upload.
7. **Verify.** `prelo check`; in Studio add a gallery section with 4+ images and two tags; confirm filter + lightbox + keyboard nav; confirm the network panel shows resized thumbs, not originals.The client edits the gallery in Studio like any section: add images from the media library, drag to reorder, set captions and tags. New tags appear as filters automatically.
Auto-generated social share images for every page and post.
Contact form with spam protection and email notifications, plus a submissions inbox in Studio.
Signup form with double opt-in, delivering to Resend, Mailchimp or Buttondown.