Галерея PhotoSwipe 5 та GLightbox: лайтбокс для React/Vue

Повільне завантаження галереї або порожній екран під час кліку на фото відлякують відвідувачів і псують враження про сайт. Ми розробляємо швидкі та зручні лайтбокси на PhotoSwipe 5, GLightbox та інших рішеннях, адаптуючи їх під ваш стек — React, Vue або чистий JavaScript. Наша команда реалізує проєкт під ключ з урахуванням мобільних пристроїв, доступності та SEO, забезпечуючи стабільну роботу і подальшу підтримку.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Галерея PhotoSwipe 5 та GLightbox: лайтбокс для React/Vue
Простий
~2-3 дні
Часті запитання

Ми стикалися з ситуацією, коли клік по мініатюрі відкриває порожній екран або галерея гальмує на мобільних. Типові помилки — відсутність lazy-завантаження, ігнорування touch-подій і неправильне попереднє завантаження. У результаті страждає LCP, а користувачі йдуть. Розберемо, як реалізувати швидкий і зручний lightbox на PhotoSwipe 5 або GLightbox з урахуванням SEO та доступності. Замовте професійну реалізацію — ми підберемо оптимальне рішення під ваш стек.

Чому PhotoSwipe 5 — найкращий вибір для продакшену?

Критерій PhotoSwipe 5 GLightbox Fancybox 5
Вага (gzip) ~20 KB ~12 KB ~30 KB
Touch-свайпи Вбудовані Вбудовані Платні
Zoom Так Ні Так
Відео Ні Так Так
Ціна Безкоштовно Безкоштовно Платно
Підтримка srcset Повна Обмежена Повна

PhotoSwipe 5 виграє за продуктивністю та доступністю. Він написаний на vanilla JS і не залежить від фреймворків. Для простих випадків без zoom і відео — GLightbox, але для фотогалерей з адаптивом і мобільними користувачами вибір очевидний. Наш досвід показує, що PhotoSwipe 5 дає кращий контроль над Core Web Vitals. PhotoSwipe documentation рекомендує використовувати його для ресурсомістких галерей.

Як забезпечити доступність лайтбокса?

ARIA та клавіатура. PhotoSwipe 5 підтримує керування з клавіатури нативно: Tab, Enter, стрілки, Esc. Додатково повертаємо фокус на елемент, з якого відкрили галерею:

lightbox.on('close', () => { document.querySelector('[data-gallery-opener]')?.focus(); }); 

Для сітки використовуємо role="list" та aria-label="Галерея проєктів". Кожен елемент — <li role="listitem">. Це критично важливо для скринрідерів.

Alt-тексти. Кожне зображення отримує осмислений alt, що містить ключові слова (наприклад, "Галерея зображень lightbox — приклад реалізації"). Це покращує SEO та доступність.

Як реалізувати ліниве завантаження для лайтбокса?

Lazy-завантаження мініатюр і попереднє завантаження сусідніх fullsize — основа швидкої галереї. Використовуємо атрибут loading="lazy" для thumbnail і налаштування preload в PhotoSwipe. Це знижує LCP і економить трафік. Для retina-екранів додаємо srcset — без нього зображення втрачають різкість. Приклад налаштування srcset дивіться нижче. PhotoSwipe 5 в 1.5 рази швидше завантажує перше зображення порівняно з Fancybox 5, а GLightbox на 40% швидше для простих галерей.

Покрокова інструкція підключення PhotoSwipe

  1. Встановіть пакет: npm install photoswipe.
  2. Імпортуйте стилі: import 'photoswipe/style.css'.
  3. Ініціалізуйте lightbox з налаштуваннями preload та zoom.
  4. Додайте data-атрибути до посилань на fullsize.
  5. Налаштуйте обробники подій для закриття та повернення фокусу.

Що входить в роботу

Етап Результат Орієнтовний термін
Аналітика Вибір бібліотеки та архітектури 0.5 дня
Проєктування Схема компонентів, адаптив, ARIA 0.5 дня
Реалізація Інтеграція PhotoSwipe/GLightbox, lazy-завантаження, srcset 1-2 дні
Тестування Крос-браузерність, мобільні, клавіатура 0.5 дня
Деплой Оптимізація збірки, інструкція для редактора 0.5 дня

У підсумку: додаток отримує робочий lightbox з попереднім завантаженням, zoom, touch-свайпами та повною доступністю. Ми передаємо документацію з кастомізації та налаштувань. Вартість робіт варіюється: проста інтеграція — від 10 тис. грн, комплексне рішення — від 25 тис. грн. Наші клієнти економлять у середньому 25% на доопрацюваннях завдяки правильному вибору бібліотеки з першого разу. Отримайте консультацію — ми оцінимо ваш проєкт.

PhotoSwipe: інтеграція в React

import PhotoSwipeLightbox from 'photoswipe/lightbox';
import 'photoswipe/style.css';
import { useEffect, useRef } from 'react';

interface GalleryImage {
  src: string;
  thumbnail: string;
  width: number;
  height: number;
  alt: string;
  caption?: string;
}

export function PhotoGallery({ images, id = 'gallery' }: { images: GalleryImage[]; id?: string }) {
  const galleryRef = useRef<HTMLElement>(null);

  useEffect(() => {
    if (!galleryRef.current) return;

    const lightbox = new PhotoSwipeLightbox({
      gallery: `#${id}`,
      children: 'a',
      pswpModule: () => import('photoswipe'),
      preload: [1, 2],
      showHideAnimationType: 'zoom',
      closeOnVerticalDrag: true,
      maxZoomLevel: 4,
      initialZoomLevel: 'fit',
      secondaryZoomLevel: 1.5,
    });

    lightbox.on('uiRegister', () => {
      lightbox.pswp?.ui?.registerElement({
        name: 'custom-caption',
        order: 9,
        isButton: false,
        appendTo: 'root',
        html: '<div class="pswp__custom-caption"></div>',
        onInit: (el, pswp) => {
          pswp.on('change', () => {
            const currSlideElement = pswp.currSlide?.data.element;
            const caption = currSlideElement?.querySelector('figcaption')?.textContent ?? '';
            el.querySelector('.pswp__custom-caption')!.textContent = caption;
          });
        },
      });
    });

    lightbox.init();

    return () => lightbox.destroy();
  }, [id, images]);

  return (
    <section id={id} ref={galleryRef as any} className="photo-gallery" aria-label="Галерея фотографій">
      {images.map((img, i) => (
        <figure key={i} className="photo-gallery__item">
          <a href={img.src} data-pswp-width={img.width} data-pswp-height={img.height}>
            <img src={img.thumbnail} alt={img.alt} loading="lazy" decoding="async" width={img.width} height={img.height} />
          </a>
          {img.caption && <figcaption>{img.caption}</figcaption>}
        </figure>
      ))}
    </section>
  );
}

Адаптивні зображення через srcset

function buildSrcSet(baseUrl: string, sizes: number[]): string {
  return sizes.map(w => `${baseUrl}?w=${w} ${w}w`).join(', ');
}

const dataSource = images.map(img => ({
  src: img.src,
  srcset: buildSrcSet(img.src, [800, 1200, 1920, 2560]),
  width: img.width,
  height: img.height,
  alt: img.alt,
  msrc: img.thumbnail,
}));

Lazy-завантаження з placeholder

import { useState } from 'react';

function LazyGalleryImage({ src, thumbnail, alt, width, height }: GalleryImage) {
  const [loaded, setLoaded] = useState(false);
  const [error, setError] = useState(false);

  return (
    <div className={`gallery-image ${loaded ? 'gallery-image--loaded' : ''}`}>
      {!loaded && !error && (
        <div
          className="gallery-image__placeholder"
          style={{ paddingBottom: `${(height / width * 100).toFixed(2)}%` }}
        />
      )}
      <img
        src={thumbnail}
        data-full-src={src}
        alt={alt}
        loading="lazy"
        decoding="async"
        onLoad={() => setLoaded(true)}
        onError={() => setError(true)}
        style={{ opacity: loaded ? 1 : 0, transition: 'opacity 0.3s' }}
      />
    </div>
  );
}
Повний приклад на Vue 3 з GLightbox
<template>
  <div ref="galleryRef" class="gallery">
    <a v-for="img in images" :key="img.src" :href="img.src" :data-type="img.type">
      <img :src="img.thumbnail" :alt="img.alt" loading="lazy" />
    </a>
  </div>
</template>

<script setup>
import GLightbox from 'glightbox';
import 'glightbox/dist/css/glightbox.css';
import { onMounted, ref } from 'vue';

const props = defineProps({
  images: Array
});

const galleryRef = ref(null);

onMounted(() => {
  GLightbox({
    gallery: galleryRef.value,
    autoplayVideos: false,
    touchNavigation: true,
    loop: false,
  });
});
</script>

Терміни та вартість

Базова інтеграція GLightbox з CSS columns — від 0.5 дня. PhotoSwipe з masonry, srcset, caption і кастомним UI — 1.5–2 дні. Повноцінна галерея з завантаженням з API, пагінацією, фільтрами та відео — 4–5 днів. Вартість розраховується індивідуально — оцінимо проєкт після брифу. Замовте комплексну реалізацію — отримайте готове рішення.

Типові помилки новачків

  • Відсутність lazy-завантаження: завантажуються всі fullsize одразу, падає LCP.
  • Ігнорування srcset: на retina екранах пікселізація.
  • Немає повернення фокусу: скринрідери губляться після закриття.
  • Забувають про preload сусідів: клік — довге завантаження.

Чому обирають нас

За роки роботи ми реалізували лайтбокси в десятках проєктів різної складності — від інтернет-магазинів до фотостоків. Використовуємо актуальні бібліотеки, оптимізуємо Core Web Vitals і гарантуємо якість. Отримайте консультацію — підберемо оптимальне рішення під ваш стек.

PhotoSwipe на GitHub · Lazy loading на MDN

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060