Lightbox
A fullscreen image viewer with gallery navigation, swipe and keyboard support.
Component
<template>
<Lightbox
v-model="showLightbox"
:images
/>
<ActionButton
text="Open lightbox"
@click="showLightbox = true"
/>
</template>
<script setup lang="ts">
const showLightbox = ref(false)
const images: GalleryImage[] = [
{ id: '1', src: '/images/river.jpg', alt: 'River between mountains', caption: 'River valley' },
{ id: '2', src: '/images/mountains.jpg', alt: 'Green mountain range', caption: 'Mountain range' },
]
</script>
Props
| Props | Required | Default | Type |
|---|---|---|---|
modelValue | — | false | boolean |
images | true | — | GalleryImage[] |
initialIndex | — | 0 | number |
loop | — | true | boolean |
showCaption | — | true | boolean |
closeOnClickOutside | — | true | boolean |
lightboxClass | — | — | string |
ariaLabel | — | — | string |
prevLabel | — | — | string |
nextLabel | — | — | string |
closeLabel | — | — | string |
fullscreenLabel | — | — | string |
Usage
modelValue
Controls whether the lightbox is open. Bind it with v-model.
<template>
<Lightbox v-model="showLightbox" :images />
</template>
images
Sets the images to display. The lightbox shows the position counter and the navigation buttons when there is more than one.
<template>
<Lightbox v-model="showLightbox" :images="images" />
</template>
<script setup lang="ts">
const images: GalleryImage[] = [
{ id: '1', src: '/images/river.jpg', alt: 'River between mountains' },
{ 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
}
initialIndex
Sets the image shown when the lightbox opens. It resets to this index every time the lightbox reopens.
<template>
<Lightbox v-model="showLightbox" :images :initialIndex="2" />
</template>
loop
Wraps around from the last image to the first, and the other way round. Set it to false to stop at both ends.
<template>
<Lightbox v-model="showLightbox" :images :loop="false" />
</template>
showCaption
Shows the caption of the current image below it.
<template>
<Lightbox v-model="showLightbox" :images :showCaption="false" />
</template>
closeOnClickOutside
Closes the lightbox when you click the backdrop around the image.
<template>
<Lightbox v-model="showLightbox" :images :closeOnClickOutside="false" />
</template>
lightboxClass
Adds custom classes to the dialog element.
<template>
<Lightbox v-model="showLightbox" :images lightboxClass="backdrop-blur-sm" />
</template>
ariaLabel
Sets the accessible name of the dialog. Falls back to useDSConfig().lightbox.dialogText().
<template>
<Lightbox v-model="showLightbox" :images ariaLabel="Product gallery" />
</template>
prevLabel
Sets the accessible name of the previous button. Falls back to useDSConfig().lightbox.previousText().
<template>
<Lightbox v-model="showLightbox" :images prevLabel="Previous photo" />
</template>
nextLabel
Sets the accessible name of the next button. Falls back to useDSConfig().lightbox.nextText().
<template>
<Lightbox v-model="showLightbox" :images nextLabel="Next photo" />
</template>
closeLabel
Sets the accessible name of the close button. Falls back to useDSConfig().actions.closeText().
<template>
<Lightbox v-model="showLightbox" :images closeLabel="Close gallery" />
</template>
fullscreenLabel
Sets the accessible name of the fullscreen button. Falls back to useDSConfig().lightbox.fullscreenText().
<template>
<Lightbox v-model="showLightbox" :images fullscreenLabel="Enter fullscreen" />
</template>
Accessibility
The lightbox renders a dialog with aria-modal, moves focus into it when it opens and returns focus to the previous element when it closes. The page scroll is locked while it is open. Image alt text is cleaned with cleanImageAlt, so screen readers do not announce "image" twice. All button labels come from useDSConfig and can be translated globally or per instance with the label props.
| Value | Description |
|---|---|
Escape | Closes the lightbox. |
ArrowLeft | Shows the previous image. |
ArrowRight | Shows the next image. |
On touch devices you can swipe left or right to change image.
Emits
| Value | Description |
|---|---|
@update:modelValue | Emits `false` when the lightbox asks to close. |
@update:index | Emits the new image index after navigating. |
@close | Emits when the lightbox is closed by the user. |
Example
<template>
<Lightbox
v-model="showLightbox"
:images
@update:index="handleIndex"
@close="handleClose"
/>
</template>
<script setup lang="ts">
const handleIndex = (index: number) => {
console.log('Showing image', index)
}
const handleClose = () => {
console.log('Lightbox closed')
}
</script>