Skip to content

Basic Configuration

Learn the fundamentals of configuring VistaView for your image galleries.

The simplest way to use VistaView requires just two things: importing the library and specifying which elements to use.

The recommended approach uses anchor tags wrapping images:

<div id="gallery">
<a href="/images/photo1-full.jpg">
<img src="/images/photo1-thumb.jpg" alt="Photo 1" />
</a>
<a href="/images/photo2-full.jpg">
<img src="/images/photo2-thumb.jpg" alt="Photo 2" />
</a>
</div>
import { vistaView } from 'vistaview';
import 'vistaview/style.css';
vistaView({
elements: '#gallery a',
});

Benefits:

  • Progressive loading from thumbnail to full-size
  • Works without JavaScript
  • SEO-friendly

You can also select images directly:

<div id="gallery">
<img src="/images/thumb1.jpg" data-vistaview-src="/images/full1.jpg" alt="Photo 1" />
<img src="/images/thumb2.jpg" data-vistaview-src="/images/full2.jpg" alt="Photo 2" />
</div>
vistaView({
elements: '#gallery img',
});

You can also pass an array of image configuration objects directly:

import type { VistaImgConfig } from 'vistaview';
const images: VistaImgConfig[] = [
{ src: '/images/photo1.jpg', alt: 'Photo 1' },
{ src: '/images/photo2.jpg', alt: 'Photo 2' },
{
src: '/images/photo3.jpg',
alt: 'Photo 3',
srcSet: '/images/photo3-800.jpg 800w, /images/photo3-1200.jpg 1200w',
},
];
vistaView({
elements: images,
});

VistaImgConfig Type:

interface VistaImgConfig {
src: string; // Full-size image URL (required)
alt?: string; // Alt text for the image
srcSet?: string; // Responsive image srcset attribute
}

Note: Thumbnails are not supported when using an array. This approach is best for programmatically generated galleries.

The vistaView function returns an instance with methods to control the lightbox programmatically:

const vista = vistaView({
elements: '#gallery a',
});
// Available methods:
vista.open(0); // Open lightbox at index 0
vista.close(); // Close the lightbox
vista.next(); // Navigate to next image
vista.prev(); // Navigate to previous image
vista.view(2); // Jump to image at index 2
vista.zoomIn(); // Zoom in
vista.zoomOut(); // Zoom out
vista.getCurrentIndex(); // Get current image index
vista.reset(); // Recalculate elements; for selectors: re-queries DOM and re-attaches click listeners; for arrays: updates element count only
vista.destroy(); // Clean up and remove lightbox

VistaInterface Type:

interface VistaInterface {
open: (startIndex?: number) => void; // Open at specific index
close: () => Promise<void>; // Close lightbox
reset: () => void; // For selectors: re-queries DOM & re-attaches click listeners; For arrays: updates count only
next: () => void; // Go to next image
prev: () => void; // Go to previous image
zoomIn: () => void; // Zoom in current image
zoomOut: () => void; // Zoom out current image
destroy: () => void; // Remove lightbox completely
getCurrentIndex: () => number; // Get current image index
view: (index: number) => void; // Navigate to specific index
}

When you need different lightbox configurations across different sections of your application, you have two main approaches:

Section titled “Approach 1: Multiple Instances (Recommended)”

Create separate VistaView instances for each gallery with different configurations:

// Product gallery with zoom enabled
const productGallery = vistaView({
elements: '#product-images a',
maxZoomLevel: 3,
arrowOnSmallScreens: true,
controls: {
topRight: ['zoomIn', 'zoomOut', 'close'],
},
});
// Portfolio gallery with minimal UI
const portfolioGallery = vistaView({
elements: '#portfolio a',
maxZoomLevel: 1, // No zoom
keyboardListeners: false,
controls: {
topRight: ['close'],
},
});
// Blog gallery with downloads
import { download } from 'vistaview/extensions/download';
const blogGallery = vistaView({
elements: '#blog-post img',
extensions: [download()],
});

Advantages:

  • Each gallery is independent with its own configuration
  • Different extensions per gallery
  • No need to reconfigure or reset
  • Straightforward and maintainable

Memory:

  • Each instance maintains its own state and event listeners
  • Automatically cleaned up when you call destroy()

Approach 2: Single Instance with Dynamic Content

Section titled “Approach 2: Single Instance with Dynamic Content”

Use a single instance and update content dynamically. The approach differs based on whether you use selectors or arrays:

Update the DOM, then call reset() to re-query elements and re-attach listeners:

const vista = vistaView({
elements: '#dynamic-gallery a',
maxZoomLevel: 2,
});
// Example Async function to fetch and update gallery
async function updateGallery(category: string) {
const response = await fetch(`/api/images?category=${category}`);
const images = await response.json();
const gallery = document.querySelector('#dynamic-gallery');
// Update DOM
gallery.innerHTML = images
.map(
(img: { src: string; alt: string }) => `
<a href="${img.src}">
<img src="${img.src}" alt="${img.alt}" />
</a>
`
)
.join('');
// Re-query DOM and re-attach click listeners
vista.reset();
}

How reset() works with selectors:

  • Re-queries the DOM using the original selector
  • Updates state.elmLength
  • Removes and re-attaches click event listeners
  • Images become clickable automatically

Mutate the array reference, then call reset() to update count:

// Create array that will be mutated
const currentImages: VistaImgConfig[] = [];
const vista = vistaView({
elements: currentImages, // Stores the array reference
maxZoomLevel: 2,
});
// Example Async function to fetch and update gallery
async function updateGallery(category: string) {
const response = await fetch(`/api/images?category=${category}`);
const images = await response.json();
// Mutate the original array (don't reassign!)
currentImages.length = 0;
currentImages.push(...images);
// Update element count
vista.reset();
}

How reset() works with arrays:

  • Reads this.elements.length to update count
  • Does NOT attach click listeners (arrays have no DOM elements)
  • You must call open() programmatically

Advantages (both):

  • Single instance reduces memory
  • Good for SPAs with dynamic content
  • All content shares same configuration

Limitations (both):

  • Cannot change configuration after initialization
  • All galleries share same settings (zoom, extensions, controls)

Always destroy instances when they’re no longer needed:

// Before page navigation in SPAs
function cleanup() {
productGallery.destroy();
portfolioGallery.destroy();
blogGallery.destroy();
}
// In React - basic cleanup
useEffect(() => {
const vista = vistaView({ elements: '#gallery a' });
return () => vista.destroy();
}, []);
// In React - destroy and recreate when data changes
const [images, setImages] = useState<VistaImgConfig[]>([]);
useEffect(() => {
const vista = vistaView({
elements: images, // Works for both: arrays, or '#gallery a' when DOM re-renders
maxZoomLevel: 2,
});
return () => vista.destroy();
}, [images]);
// In Vue
onUnmounted(() => {
vista.destroy();
});
  • Use multiple instances when galleries need different configurations (zoom, extensions, controls)
  • Use single instance with array for programmatic galleries in SPAs where all galleries share configuration
  • Use selector updates for simple galleries where only the image set changes
GitHubnpmllms.txtContext7

© 2026 • MIT License