3.0.0
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 thelightgallery/reactwrapper.@lightgallery/vue, new native Vue 3 package.v-modelfor the open state, slots,Teleport. Replaces thelightgallery/vuewrapper.@lightgallery/angular, new native Angular package. Standalone components, signal inputs, zoneless change detection, CDK overlay. Replaces thelightgallery/angularwrapper.lightgallery, the vanilla package, modernized build with anexportsmap; plugins remain separate entries underlightgallery/plugins/*.
- Justified layout plugin: row-justified trigger grids from the gallery itself (
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.justifiedRevealpicks whether rows fill in top to bottom or each thumbnail appears on its own. Shipclass="lg-justified"in the container markup so the hiding also covers the window before the script runs. - Origin crop plugin (
lightgallery/plugins/originCrop, and in each framework package): the zoom-from-origin flight from a cropped thumbnail. A tile cropped withobject-fit: coverorbackground-size: covershows 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. - Toolbar overflow: the toolbar stays on one row. When its buttons do not fit beside the counter, the lowest-priority ones move into a "More options" menu (
toolbarOverflow, on by default), labelled bystrings.moreOptionsand drawn with the replaceablemoreicon. Touch devices also leave out the zoom in, zoom out and actual size buttons, which repeat pinch and double-tap (showGestureButtons, turned off throughmobileSettings). - Zoom from origin in dynamic mode: a dynamic gallery now flies open from the element passed to
openGallery(index, element), and closes with the centre fade, like the framework packages. The media size comes from the newlgSizeitem field (data-lg-sizeon markup items fills the same field), or from adata-lg-sizeattribute on that element. Dynamic galleries used to forcezoomFromOriginoff. - Virtualization:
virtualizationsetting keeps a window of slides and thumbnails mounted for very large galleries. - Video facades: video slides render a poster and load the player on first play;
videoFacadeandyouTubeNoCookiesettings. - Thumbnail scrubbing:
scrubThumbnailsturns the thumbnail strip into a scrubber that drives the gallery through the release glide. - Custom icons:
iconssetting (Reactrender.icon, Vue:icons, AngularlgIcontemplate) replaces any control icon by name. Built-in icons are inline SVG; the icon font is gone. - Localization and RTL: every UI string is a setting (
strings, merged per key over the defaults);directionsetting with an opt-inlg-rtl.csslayer that mirrors navigation, swipe and chrome. - Web Share: the share button prefers the device's native share sheet (
preferNativeShare) with the social links as fallback; X replaces the Twitter target. - Hash drivers:
hashDriverchooses between the hash, history and Navigation API drivers behind one interface. - Responsive loading: size ladders and
srcset/sizesselection for the lightbox image, with decode-gated slide completion. - Accessibility: dialog semantics, focus trapping and restoration, labelled controls from
strings, a polite live region announcing slide changes (ariaAnnouncements), reduced-motion support. - Gesture physics: releases run a velocity-seeded damped spring with momentum projection; boundary friction instead of hard clamps; pinch-to-close (
pinchToClose); aflickVelocitysetting. - Public types:
lightgalleryexports theLightGalleryinstance type (for a variable or a plugin'score, withoutReturnType),LightGallerySettings,GalleryItemand every eventdetailtype (InitDetail,BeforeSlideDetail, …) from the package entry:import type { LightGallerySettings } from 'lightgallery'.
- Icons are inline SVG; the
lgicon font and its files are removed. - Plugin labels (aria-labels and titles) come from the core
stringssetting; the per-plugin*PluginStringssettings are deprecated aliases. - The share plugin's Twitter target is now X: the
shareXicon name, and the X mark in place of the old bird. lightgallerydeclares Node 18 as its minimum inengines, matching the other packages.- In the React, Vue and Angular packages the zoom plugin's actual-size button now follows the vanilla behaviour: it carries the
zoomInandzoomOuticons and switches between theactualSizeIconsclasses with the zoom state, while the zoom in and zoom out buttons keep their fixedlg-zoom-inandlg-zoom-outclasses. The button is 24px like every other toolbar icon in all packages. TheactualSizeicon name is no longer used by any default rendering. - In the React, Vue and Angular packages
initis always the first event: a gallery mounted already open firesinit, thenbeforeOpenandafterOpen, as the vanilla gallery does (the betas firedbeforeOpenfirst).
Long-standing bugs, nearly all of them present in 2.x:
-
The vanilla focus trap counts every focusable element in the dialog, including
tabindexones, so Tab cannot leave through plugin content. -
A thumbnail click that moved by a few pixels started a strip drag: with
scrubThumbnailson, 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 thanthumbnailSwipeThresholdis 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 anhrefunless you passed one, so keyboard users could not tab to the thumbnails and the server-rendered markup linked nowhere. An anchor trigger now links toitem.srcby default, as the Vue<LgItem>already did; an explicithrefstill 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
NaNand 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'saria-expandedtracks 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.
- The
lightgallery/react,lightgallery/vueandlightgallery/angularwrappers, replaced by the native packages above. - The share dropdown's
.lg-dropdown-overlayelement. - The
supportLegacyBrowsersetting and the responsive-image polyfill hook behind it, along with theCustomEventandElement.matchespolyfills and the old-browser scroll fallbacks. Galleries withsrcsetor<picture>sources no longer log a warning asking for a polyfill. - Vendor prefixes in the stylesheets. The CSS carried
-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-visibilitystays 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. - The
mozandmsfullscreen API fallbacks in the vanilla fullscreen plugin. Thewebkitfallback stays for Safari before 16.4, as in the framework packages.
See the migration guide for the upgrade steps.
2.9.0
- fix(lg-zoom): avoid reference error when containerRect in not defined #1684 - Author - @felix-berlin
- Move all scss
@importto@use/@forward#1697 - Author - @joeworkman
Replaced all deprecated SCSS @import statements with the modern @use / @forward syntax. This improves maintainability and performance, but may break setups where you override lightGallery variables.
If you're not overriding any SCSS variables, nothing changes for you. But if you are, you'll now need to pass them at the time of use, like this:
@use 'lg-variables' as * with (
$lg-theme-color: #f00
);
Overrides must be defined before importing lightGallery styles. Avoid mixing @import and @use in the same file.
2.9.0-beta.1
- fix(lg-zoom): avoid reference error when containerRect in not defined #1684 - Author - @felix-berlin
- Move all scss
@importto@use/@forward#1697 - Author - @joeworkman
Replaced all deprecated SCSS @import statements with the modern @use / @forward syntax. This improves maintainability and performance, but may break setups where you override lightGallery variables.
If you're not overriding any SCSS variables, nothing changes for you. But if you are, you'll now need to pass them at the time of use, like this:
@use 'lg-variables' as * with (
$lg-theme-color: #f00
);
Overrides must be defined before importing lightGallery styles. Avoid mixing @import and @use in the same file.
Version 2.8.3 release
https://github.com/sachinchoolur/lightGallery/pull/1674 Remove unnecessary debug log
Version 2.8.2 release
Fix issue: Vue bundle missing from npm package #1671
This issue occurred due to a Node.js version error, causing the build to silently fail while simultaneously creating builds for all frameworks.
Version 2.8.1 release
- Typo fix by @gilren in https://github.com/sachinchoolur/lightGallery/pull/1547
- refactor(container): add type () => HTMLElement & string selector support - https://github.com/sachinchoolur/lightGallery/pull/1570
- Fix #1524 - Cannot override muted param with Vimeo video by @dev-newvisibility in https://github.com/sachinchoolur/lightGallery/pull/1526
- fix: resolve subHtmlUrl dynamic mode issue in fetchCaptionFromUrl by @ajuzp5 in https://github.com/sachinchoolur/lightGallery/pull/1557
- fix: refactor inline styles in thumbnail plugin for CSP compatibility in https://github.com/sachinchoolur/lightGallery/pull/1565
- fix(lg-utils): update dummy img handling & append method by @bytesandbots3 in https://github.com/sachinchoolur/lightGallery/pull/1596
- fix(lg-rotate): block the ability to close the zoomed-in image #1581 in https://github.com/sachinchoolur/lightGallery/pull/1594
- feat: wrap img with & add data-lg-size in https://github.com/sachinchoolur/lightGallery/pull/1597
- fix(lgzoom): correct zoom out aria-label and icon issue #1583 in https://github.com/sachinchoolur/lightGallery/pull/1591
- fix(lg-zoom): resolve undefined property access #1576 in https://github.com/sachinchoolur/lightGallery/pull/1595
- fix: correct iframe container styles to display external content #1600 in https://github.com/sachinchoolur/lightGallery/pull/1603
- fix(types): add lgMediumZoom plugin typings #1607 by @bytesandbots3 in https://github.com/sachinchoolur/lightGallery/pull/1608
Version 2.8.0-beta.2 release
- Typo fix by @gilren in https://github.com/sachinchoolur/lightGallery/pull/1547
- refactor(container): add type () => HTMLElement & string selector support - https://github.com/sachinchoolur/lightGallery/pull/1570
- Fix #1524 - Cannot override muted param with Vimeo video by @dev-newvisibility in https://github.com/sachinchoolur/lightGallery/pull/1526
- fix: resolve subHtmlUrl dynamic mode issue in fetchCaptionFromUrl by @ajuzp5 in https://github.com/sachinchoolur/lightGallery/pull/1557
- fix: refactor inline styles in thumbnail plugin for CSP compatibility in https://github.com/sachinchoolur/lightGallery/pull/1565
- fix(lg-utils): update dummy img handling & append method by @bytesandbots3 in https://github.com/sachinchoolur/lightGallery/pull/1596
- fix(lg-rotate): block the ability to close the zoomed-in image #1581 in https://github.com/sachinchoolur/lightGallery/pull/1594
- feat: wrap img with & add data-lg-size in https://github.com/sachinchoolur/lightGallery/pull/1597
- fix(lgzoom): correct zoom out aria-label and icon issue #1583 in https://github.com/sachinchoolur/lightGallery/pull/1591
- fix(lg-zoom): resolve undefined property access #1576 in https://github.com/sachinchoolur/lightGallery/pull/1595
- fix: correct iframe container styles to display external content #1600 in https://github.com/sachinchoolur/lightGallery/pull/1603
- fix(types): add lgMediumZoom plugin typings #1607 by @bytesandbots3 in https://github.com/sachinchoolur/lightGallery/pull/1608
Version 2.8.0-beta.1 release
Angular 16, 17 build
Version 2.7.2 release
- Add alt tag for thumbnails if available
- Infinite zoom (Zoom beyond actual size) support.
- enable the close button on mobile for iframe
- fix(zoom): zoom in and out not happening when clicked too fast
- feat(strings): make error message customizable
Version 2.7.2-beta.1 release
- Add alt tag for thumbnails if available