Component
Props
| Props | Required | Default | Type |
|---|---|---|---|
images | true | — | GalleryImage[] |
cols | — | 3 | number |
tabletCols | — | 2 | number |
mobileCols | — | 1 | number |
gapClass | — | 'gap-4' | string |
aspectRatio | — | AspectRatio.AR_1_1 | AspectRatio |
fit | — | ImageFit.COVER | ImageFit |
hoverEffect | — | ImageHoverEffect.ZOOM_IN | ImageHoverEffect |
hoverSplitDirection | — | ImageHoverSplitDirection.DIAGONAL | ImageHoverSplitDirection |
captionPlacement | — | ImageCaptionPlacement.NONE | ImageCaptionPlacement |
paginationMode | — | GalleryPaginationMode.NONE | GalleryPaginationMode |
itemsPerPage | — | 12 | number |
page | — | — | number |
loadMoreText | — | useDSConfig().gallery.loadMoreText() | string |
paginationProps | — | — | Record<string, unknown> |
useLightbox | — | true | boolean |
useLightboxLoop | — | true | boolean |
showLightboxCaption | — | true | boolean |
useNuxtImg | — | false | boolean |
sizes | — | — | string |
densities | — | — | string |
loading | — | ImageLoading.LAZY | ImageLoading |
containerClass | — | — | string |
imageClass | — | — | string |
captionClass | — | — | string |
paginationClass | — | — | string |
Usage
images
Sets the images to display. Each one becomes an Image in the grid and a slide in the lightbox.
<template>
<Gallery :images />
</template>
<script setup lang="ts">
const images: GalleryImage[] = [
{ id: '1', src: '/images/river.jpg', alt: 'River between mountains', caption: 'River valley' },
{ id: '2', src: '/images/lake.jpg', alt: 'Quiet lake', caption: 'Quiet lake' },
]
</script>
TypeScript Interface
interface GalleryImage {
id: string
src: string
alt: string // Redundant wording such as "Image of" is removed with cleanImageAlt
caption?: string | null
width?: number
height?: number
}
cols
Sets the number of columns on desktop.
<template>
<Gallery :images :cols="4" />
</template>
tabletCols
Sets the number of columns on tablet.
<template>
<Gallery :images :tabletCols="3" />
</template>
mobileCols
Sets the number of columns on mobile.
<template>
<Gallery :images :mobileCols="2" />
</template>
gapClass
Sets the gap between images with a Tailwind class.
<template>
<Gallery :images gapClass="gap-8" />
</template>
aspectRatio
Crops every image to the same ratio via the AspectRatio enum, which keeps the grid aligned even when the sources have different sizes.
<template>
<Gallery :images :aspectRatio="AspectRatio.AR_4_3" />
</template>
Options
| Value | Description |
|---|---|
AR_1_1 | 1:1 |
AR_4_3 | 4:3 |
AR_3_2 | 3:2 |
AR_16_9 | 16:9 |
AR_3_4 | 3:4 |
AR_4_5 | 4:5 |
AR_2_3 | 2:3 |
fit
Sets how each image fills its box via the ImageFit enum.
<template>
<Gallery :images :fit="ImageFit.CONTAIN" />
</template>
Options
| Value | Description |
|---|---|
COVER | cover |
CONTAIN | contain |
hoverEffect
Sets the hover effect of every image via the ImageHoverEffect enum.
<template>
<Gallery :images :hoverEffect="ImageHoverEffect.GRAYSCALE" />
</template>
Options
| Value | Description |
|---|---|
NONE | none |
ZOOM_IN | zoomIn |
ZOOM_OUT | zoomOut |
OVERLAY | overlay |
BLUR | blur |
GRAYSCALE | grayscale |
SPLIT_ZOOM | splitZoom |
hoverSplitDirection
Sets the separation direction of the SPLIT_ZOOM effect.
<template>
<Gallery
:images
:hoverEffect="ImageHoverEffect.SPLIT_ZOOM"
:hoverSplitDirection="ImageHoverSplitDirection.VERTICAL"
/>
</template>
Options
| Value | Description |
|---|---|
DIAGONAL | diagonal |
HORIZONTAL | horizontal |
VERTICAL | vertical |
captionPlacement
Sets where the image captions are displayed on the grid. They are hidden by default and are still shown in the lightbox.
<template>
<Gallery :images :captionPlacement="ImageCaptionPlacement.BELOW" />
</template>
Options
| Value | Description |
|---|---|
NONE | none |
BELOW | below |
OVERLAY_BOTTOM | overlayBottom |
HOVER | hover |
paginationMode
Sets how the images are split via the GalleryPaginationMode enum. The lightbox always navigates through the whole list, whatever the page.
<template>
<Gallery
:images
:paginationMode="GalleryPaginationMode.LOAD_MORE"
:itemsPerPage="9"
/>
</template>
Options
| Value | Description |
|---|---|
NONE | Shows every image. |
BUTTONS | Shows one page at a time with numbered buttons (`ButtonPagination`). |
SIMPLE | Shows one page at a time with previous and next buttons (`SimplePagination`). |
LOAD_MORE | Shows a button that adds the next batch below the current images. |
INFINITE | Adds the next batch automatically when you scroll to the end of the grid. |
itemsPerPage
Sets how many images are shown per page, or per batch with LOAD_MORE and INFINITE.
<template>
<Gallery
:images
:paginationMode="GalleryPaginationMode.BUTTONS"
:itemsPerPage="6"
/>
</template>
page
Sets the current page. Bind it with v-model:page to control or read it from outside. Without it, the gallery keeps its own page state. With LOAD_MORE and INFINITE it is the number of batches shown. Out of range values are clamped.
<template>
<Gallery
v-model:page="page"
:images
:paginationMode="GalleryPaginationMode.BUTTONS"
/>
</template>
<script setup lang="ts">
const page = ref(1)
</script>
loadMoreText
Sets the text of the button shown with LOAD_MORE. Falls back to useDSConfig().gallery.loadMoreText().
<template>
<Gallery
:images
:paginationMode="GalleryPaginationMode.LOAD_MORE"
loadMoreText="Show more photos"
/>
</template>
paginationProps
Passes extra props to the pagination component, either ButtonPagination or SimplePagination. Use it to translate the result texts and aria labels for this gallery only. To translate them everywhere, set useDSConfig().pagination once instead. The pagination props the gallery controls itself, such as the page and the total, can't be overridden.
<template>
<Gallery
:images
:paginationMode="GalleryPaginationMode.BUTTONS"
:paginationProps="{
resultTextMultiplePages: 'Mostrando {from} a {to} de {total} imágenes',
ariaLabelPrevious: 'Página anterior',
ariaLabelNext: 'Página siguiente',
}"
/>
</template>
useLightbox
Opens a single Lightbox on the clicked image, so you can navigate through the whole gallery. Set it to false for a static grid.
<template>
<Gallery :images :useLightbox="false" />
</template>
useLightboxLoop
Wraps the lightbox navigation around at both ends.
<template>
<Gallery :images :useLightboxLoop="false" />
</template>
showLightboxCaption
Shows the image caption inside the lightbox.
<template>
<Gallery :images :showLightboxCaption="false" />
</template>
useNuxtImg
Renders every image with NuxtImg from @nuxt/image. It requires the @nuxt/image module in your app.
<template>
<Gallery :images useNuxtImg sizes="100vw md:50vw lg:33vw" />
</template>
sizes
Sets the sizes attribute passed to NuxtImg. It only applies with useNuxtImg.
<template>
<Gallery :images useNuxtImg sizes="100vw md:50vw" />
</template>
densities
Sets the densities attribute passed to NuxtImg. It only applies with useNuxtImg.
<template>
<Gallery :images useNuxtImg densities="x1 x2" />
</template>
loading
Sets how the browser loads every image via the ImageLoading enum. Images are lazy by default. Use EAGER when the gallery is above the fold.
<template>
<Gallery :images :loading="ImageLoading.EAGER" />
</template>
Options
| Value | Description |
|---|---|
LAZY | lazy |
EAGER | eager |
containerClass
Adds custom classes to the root element.
<template>
<Gallery :images containerClass="max-w-4xl mx-auto" />
</template>
imageClass
Adds custom classes to every img element.
<template>
<Gallery :images imageClass="object-top" />
</template>
captionClass
Adds custom classes to every caption.
<template>
<Gallery :images captionClass="text-center" />
</template>
paginationClass
Adds custom classes to the element that wraps the pagination or the load more button.
<template>
<Gallery
:images
:paginationMode="GalleryPaginationMode.BUTTONS"
paginationClass="mt-10"
/>
</template>
Accessibility
Each image is a native button when the lightbox is on, so the gallery works with Tab, Enter and Space. Alt text comes from each GalleryImage. The pagination components are native navigation with labelled buttons. With INFINITE, the sentinel that triggers loading is hidden from assistive technology, so prefer LOAD_MORE when keyboard and screen reader users need to control when more images appear. Inside the lightbox you can use the arrow keys to navigate and Escape to close it. See the Lightbox accessibility notes.
Emits
| Value | Description |
|---|---|
@click | Emits the clicked `GalleryImage` and its index in the full list when an image is clicked with `useLightbox` on. |
@update:page | Emits the new page number when the page changes, from the pagination, the load more button or infinite scroll. |
Example
<template>
<Gallery :images @click="handleClick" />
</template>
<script setup lang="ts">
const handleClick = (image: GalleryImage, index: number) => {
console.log('Clicked', image.id, index)
}
</script>