All notable changes to lightGallery. The format follows Keep a Changelog; versions follow Semantic Versioning.
Published under the latest tag for every package: lightgallery,
@lightgallery/headless, @lightgallery/react, @lightgallery/vue and
@lightgallery/angular, all at 3.0.0. The 3.0.0 betas were published under
next; @lightgallery/headless@3.0.0-beta.1 shipped without its build
output and is deprecated.
Version 3 is a complete rewrite of lightGallery around a shared, framework-free core, with native packages for React, Vue and Angular and performance and experience improvements throughout. The vanilla API is unchanged, so a 2.x gallery keeps working.
@lightgallery/headless, new. The gallery’s logic without a DOM:
state machine, settings resolution, gesture and zoom math, thumbnail
windowing, URL drivers, video URL helpers. Every package below builds on it.@lightgallery/react, new native React package. Components, render
slots, callbacks and an imperative handle; React owns every DOM node.
Replaces the lightgallery/react wrapper.@lightgallery/vue, new native Vue 3 package. v-model for the open
state, slots, Teleport. Replaces the lightgallery/vue wrapper.@lightgallery/angular, new native Angular package. Standalone
components, signal inputs, zoneless change detection, CDK overlay.
Replaces the lightgallery/angular wrapper.lightgallery, the vanilla package, modernized build with an
exports map; plugins remain separate entries under lightgallery/plugins/*.lightgallery/plugins/justified, and grid components in each
framework package). The grid is never seen unorganised: thumbnails stay
out of flow until the layout has positioned them, each box then shows as
a placeholder and its thumbnail fades in once loaded. justifiedReveal
picks whether rows fill in top to bottom or each thumbnail appears on
its own. Ship class="lg-justified" in the container markup so the
hiding also covers the window before the script runs.lightgallery/plugins/originCrop, and in each
framework package): the zoom-from-origin flight from a cropped thumbnail.
A tile cropped with object-fit: cover or background-size: cover shows
a window of the photo, and the built-in flight squashes the whole photo
into it; with the plugin that window grows from the tile at a uniform
scale while the rest of the photo is revealed around it, and the close
flies back the same way. It reads the thumbnail’s computed fit, so no
markup or stylesheet is needed.toolbarOverflow, on by default), labelled by
strings.moreOptions and drawn with the replaceable more icon. Touch
devices also leave out the zoom in, zoom out and actual size buttons,
which repeat pinch and double-tap (showGestureButtons, turned off
through mobileSettings).openGallery(index, element), and closes
with the centre fade, like the framework packages. The media size comes
from the new lgSize item field (data-lg-size on markup items fills
the same field), or from a data-lg-size attribute on that element.
Dynamic galleries used to force zoomFromOrigin off.virtualization setting keeps a window of slides and
thumbnails mounted for very large galleries.videoFacade and youTubeNoCookie settings.scrubThumbnails turns the thumbnail strip into
a scrubber that drives the gallery through the release glide.icons setting (React render.icon, Vue :icons,
Angular lgIcon template) replaces any control icon by name. Built-in
icons are inline SVG; the icon font is gone.strings, merged
per key over the defaults); direction setting with an opt-in
lg-rtl.css layer that mirrors navigation, swipe and chrome.preferNativeShare) with the social links as fallback; X replaces the
Twitter target.hashDriver chooses between the hash, history and
Navigation API drivers behind one interface.srcset/sizes selection for
the lightbox image, with decode-gated slide completion.strings, a polite live region announcing slide
changes (ariaAnnouncements), reduced-motion support.pinchToClose); a flickVelocity setting.lightgallery exports the LightGallery instance
type (for a variable or a plugin’s core, without ReturnType),
LightGallerySettings, GalleryItem and every event detail type
(InitDetail, BeforeSlideDetail, …) from the package entry:
import type { LightGallerySettings } from 'lightgallery'.lg icon font and its files are removed.strings
setting; the per-plugin *PluginStrings settings are deprecated aliases.shareX icon name, and
the X mark in place of the old bird.lightgallery declares Node 18 as its minimum in engines, matching
the other packages.zoomIn and
zoomOut icons and switches between the actualSizeIcons classes with
the zoom state, while the zoom in and zoom out buttons keep their fixed
lg-zoom-in and lg-zoom-out classes. The button is 24px like every
other toolbar icon in all packages. The actualSize icon name is no
longer used by any default rendering.init is always the first event:
a gallery mounted already open fires init, then beforeOpen and
afterOpen, as the vanilla gallery does (the betas fired beforeOpen
first).Long-standing bugs, nearly all of them present in 2.x:
The vanilla focus trap counts every focusable element in the dialog,
including tabindex ones, so Tab cannot leave through plugin content.
A thumbnail click that moved by a few pixels started a strip drag: with
scrubThumbnails on, the release glide kept the scrub session alive and
the click’s own slide change did not re-centre the strip, and on a long
strip the wobble itself navigated (one pixel is several slides). A press
that moves less than thumbnailSwipeThreshold is a click in every
package: it neither scrubs nor glides.
In a windowed vanilla strip (virtualization.thumbs) the previous
thumbnail also kept its active mark after a slide change, and a wobble
toward either end of the strip rebuilt it under the pointer (the elastic
overshoot read as travel past the rendered window), which swallowed the
click; the frameworks committed a translate mid-drag for the same reason.
Closing a zoomed image in the React, Vue and Angular packages left it enlarged: the close flight shrank the slide around the zoom wrappers, so the image flew back to its trigger at the zoomed scale, covering the thumbnails and the page around it. The zoom now resets in the same frame the close starts, as in vanilla, and the image lands on its thumbnail.
The slideshow ran on a fixed interval, so on a slow connection it advanced past images that had not loaded yet. The countdown (and the progress bar) now starts once the slide on screen has loaded; a slide that fails to load settles the same way, so a broken image does not stall the show.
In the React, Vue and Angular packages a slide that left the mounted pool kept its loaded flag, so returning to it in a large gallery showed no loader while the image downloaded again.
The React <LightGalleryItem> and an Angular [lgGalleryItem] anchor
rendered without an href unless you passed one, so keyboard users
could not tab to the thumbnails and the server-rendered markup linked
nowhere. An anchor trigger now links to item.src by default, as the
Vue <LgItem> already did; an explicit href still wins.
Slide transitions crossfaded for the whole slide instead of the brief fade the modes ask for, so the outgoing image ghosted across the transition. Transform and opacity now keep their own durations, and the modes whose effect is the fade keep the long one.
Zoom clamped a repositioning zoom against a wider window than its own release settle uses. Zooming near an edge parked the image where the next tap immediately moved it away from.
Rotating an image and then zooming divided by a zero previous scale,
handing the pan origin NaN and voiding the transform, so panning
silently stopped tracking.
Medium zoom closed the gallery on every click, toolbar buttons included, so rotating or sharing dismissed the image. Toolbar clicks now leave it open; a click on the slide or backdrop still closes.
The thumbnail strip animated its first positioning, so opening the gallery from a thumbnail far along the strip slid it across while the image was still flying in. That first positioning is now instant.
The thumbnail strip is built when the gallery initialises, and its images loaded eagerly, so every page with a closed gallery downloaded all of its strip thumbnails at load. Strip images are now lazy; nothing is fetched until the gallery opens, and thumbs far along the strip load as they scroll into view.
The share dropdown hung from the toolbar’s corner instead of the share
button, so on narrow screens it opened nowhere near the control (and its
arrow pointed at the wrong one). Button and menu now share a wrapper that
anchors the menu under the button, which also gets the list out of the
<button> it was nested in. Closing the gallery with the dropdown open
left it open on the next open; it now closes with the gallery, and the
share button’s aria-expanded tracks it.
The share dropdown stayed open while the other toolbar buttons and the arrows were used: its dimming overlay sat below the toolbar, so only a click on the slide dismissed it, and Escape closed the whole gallery instead. The dropdown now dismisses like the More options menu: on a press anywhere outside it, on Escape (the gallery stays open) and when focus tabs out of it. A dismissing tap on the backdrop no longer also closes the gallery, for the More options menu as well.
lightgallery/react, lightgallery/vue and lightgallery/angular
wrappers, replaced by the native packages above..lg-dropdown-overlay element.supportLegacyBrowser setting and the responsive-image polyfill
hook behind it, along with the CustomEvent and Element.matches
polyfills and the old-browser scroll fallbacks. Galleries with srcset
or <picture> sources no longer log a warning asking for a polyfill.-webkit-, -moz-,
-ms- and -o- copies of every transform, transition, animation and
grab cursor; every supported browser reads the standard properties, so
the bundle is about a quarter smaller and Angular’s critical-CSS step no
longer warns about the prefixed keyframes. -webkit-backface-visibility
stays for iOS Safari before 15.4. The SCSS mixins keep their names and
now emit the standard property, so stylesheets that include them still
compile.moz and ms fullscreen API fallbacks in the vanilla fullscreen
plugin. The webkit fallback stays for Safari before 16.4, as in the
framework packages.See the migration guide for the upgrade steps.
Release notes for the 2.x line are on GitHub releases.