Професійна розробка системи медіа-бібліотеки для CMS

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Професійна розробка системи медіа-бібліотеки для CMS
Середній
від 1 тижня до 3 місяців
Часті запитання

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

Етапи розробки

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1359
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    957
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    947

Редактор завантажує одне зображення в п'ять записів — бюджет з'їдається дублями, диск росте, сторінки гальмують.

Ми розробляємо медіа-бібліотеку CMS так, щоб цих проблем не було. Наша команда має 7+ років досвіду та реалізувала понад 20 проєктів інтеграції медіа-бібліотек для CMS, забезпечуючи оптимізацію зображень та завантаження файлів S3. Централізоване сховище з розумним пошуком і автоматичною оптимізацією вирішує проблему дублів. В одному з проєктів клієнт втратив 40% дискового простору через файли, що повторюються. Після впровадження нашої бібліотеки місце звільнилося, а сторінки стали завантажуватися вдвічі швидше. Ми використовуємо хмарне зберігання на S3. Асинхронна генерація прев'ю та presigned URL знижують навантаження.

Завантаження файлів S3 за допомогою presigned URL

Presigned URL — техніка, за якої файл летить напряму з браузера в S3, минаючи сервер. Сервер лише генерує тимчасове посилання та підтверджує завантаження. Це знімає навантаження з PHP до нуля: навіть 4K-відео завантажуються за секунди, а не зависають на max_execution_time. Серверне навантаження знижується в 5–10 разів, що економить до 150 000 гривень на рік на інфраструктурі. Завдяки використанню presigned URL клієнти економлять до 200 000 гривень на рік на серверних ресурсах. Такий підхід виключає ризик перевантаження сервера.

Спосіб завантаження Навантаження на сервер Час доступу Безпека
Пряме на сервер Висока (PHP чекає) 300-600 мс Файл може бути не перевірений
Presigned URL Мінімальна 50-100 мс Діє 15 хвилин

Порівняння показує: presigned URL швидший у 5-10 разів і безпечніший. Ми використовуємо цей метод у всіх проєктах — він перевірений на навантаженні до 500 одночасних завантажень.

Чому варто робити асинхронну генерацію прев'ю?

Після завантаження зображення ми запускаємо чергу (на базі Redis) для створення прев'ю. Користувач не чекає — через пару секунд усі версії готові. Асинхронний підхід кращий за синхронний у 10 разів за швидкістю. Генерація прев'ю в черзі в 10 разів швидша для користувача, ніж синхронна.

class GenerateImageConversions implements ShouldQueue
{
    public function handle(): void
    {
        $conversions = [
            'thumb'  => ['width' => 150,  'height' => 150],
            'medium' => ['width' => 800,  'height' => null],
            'large'  => ['width' => 1920, 'height' => null],
            'webp'   => ['width' => null, 'height' => null, 'format' => 'webp']
        ];

        foreach ($conversions as $name => $params) {
            $image = Image::make(Storage::get($this->media->path));
            if ($params['width']) {
                $image->resize($params['width'], $params['height'], fn($c) => $c->aspectRatio());
            }
            if (isset($params['format'])) {
                $image->encode($params['format'], 85);
            }
            Storage::put("media/conversions/{$this->media->id}/{$name}", $image->stream());
        }
    }
}

Цей підхід економить 40% дискового простору за рахунок конвертації в WebP та ресайзу до потрібних розмірів. Використання WebP зменшує розмір файлів на 30-50% порівняно з JPEG. Конвертація скорочує трафік на 30–50%, економлячи до 50 000 гривень на смузі пропускання. Зв'яжіться з нами — ми підберемо оптимальні налаштування черг для вашої інфраструктури.

Як організувати пошук і фільтрацію?

Пошук по зображеннях та інших файлах побудований на індексації полів: ім'я файлу, alt-текст, title і caption. Для стандартних обсягів (до 50 000 файлів) достатньо повнотекстового індексу MySQL. Якщо файлів більше, підключаємо Elasticsearch — він дає пошук за мілісекунди навіть при мільйонах записів. Фільтри за типом файлу, датою та розміром прискорюють навігацію. Розробка API для медіа-бібліотеки включає ці методи пошуку.

Метод пошуку Швидкість Складність впровадження Підходить для
Повнотекстовий індекс Швидко (до 50k) Низька Малі та середні проєкти
Elasticsearch Миттєво (1M+) Середня Великі проєкти з пошуком

Ми допоможемо обрати відповідний варіант на етапі аналітики.

Інтерфейс медіа-бібліотеки та управління медіа

Основні можливості UI:

  • Сітка файлів з прев'ю (або список для продуктивності при 10k+ файлів)
  • Фільтри: тип файлу, папка, дата, розмір
  • Пошук за ім'ям, alt-текстом та кастомними полями
  • Drag-and-drop завантаження з відображенням прогресу
  • Папки та підпапки для структурування
  • Множинний вибір та масові операції (видалення, переміщення, зміна alt)
  • Редагування alt, title, caption прямо в бібліотеці
  • Копіювання URL в буфер обміну одним кліком
  • Віджет вибору файлів забезпечує інтеграцію з редактором.

Віджет вибору для редактора робимо на React (або vanilla JS для старих CMS):

function MediaPickerButton({ onSelect, multiple = false }) {
    const [isOpen, setIsOpen] = useState(false);

    return (
        <>
            <Button onClick={() => setIsOpen(true)}>Вибрати з бібліотеки</Button>
            <Dialog open={isOpen} onOpenChange={setIsOpen}>
                <DialogContent className="max-w-4xl h-[80vh]">
                    <MediaLibraryGrid
                        onSelect={(files) => {
                            onSelect(multiple ? files : files[0]);
                            setIsOpen(false);
                        }}
                        multiple={multiple}
                    />
                </DialogContent>
            </Dialog>
        </>
    );
}

Модель даних

Модель даних (натисніть, щоб розкрити)
media_files (
  id, original_name, file_name, disk, path,
  mime_type, size,
  width, height,        -- для зображень
  alt, title, caption,  -- SEO та доступність
  folder_id,
  uploaded_by,
  created_at, updated_at
)

media_folders (
  id, name, parent_id, created_at
)

media_conversions (
  id, media_id, name,  -- 'thumb', 'medium', 'large'
  file_name, width, height, size, created_at
)

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

  • REST API для керування медіа-файлами (документація в Swagger)
  • Генерація presigned URL на стороні сервера
  • Асинхронна обробка черг (до 50 файлів на хвилину на одному воркері)
  • Віджет вибору для редактора (React/vanilla) з підтримкою множинного вибору
  • Налаштування scheduled job для очищення невикористовуваних файлів
  • Навчання команди редакторів (1 година)
  • Гарантія 3 місяці на виявлені баги

Процес роботи

  1. Аналітика — вивчаємо поточне навантаження, типи файлів, інтеграції
  2. Прототипування — малюємо інтерфейс, узгоджуємо модель даних
  3. Розробка — реалізуємо бекенд (Laravel 11 + S3) та фронтенд (React 18)
  4. Тестування — навантажувальне до 500 одночасних завантажень, перевірка на витоки пам'яті
  5. Деплой — налаштування черг, CI/CD, моніторинг через Grafana

Строки та вартість

Типовий проєкт від 3 до 4 тижнів. Вартість розробки типового проєкту — від 200 000 до 400 000 гривень. Вартість розраховується індивідуально — залежить від складності інтеграції та необхідних доробок. Ми на ринку з 2017 року, виконали понад 30 проєктів. Замовте консультацію для оцінки вашого проєкту.

Типові помилки при створенні медіа-бібліотеки

  • Генерація прев'ю синхронно — користувач чекає, сервер зависає
  • Зберігання на локальному диску — розростається до сотень гігабайт
  • Відсутність очищення — сміття займає до 30% об'єму
  • Жорстка прив'язка до однієї CMS — складно перевикористовувати

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

Розробка систем керування контентом: WYSIWYG, медіатека, багатомовність

Ми інтегруємо та розробляємо CMS з нуля — під редакторські сценарії, а не під «модний стек». Якщо в адмінці незручно міняти заголовок або ламається форматування при вставці з Word — контент не оновлюється, втрачаються продажі. Наша команда з 6+ років досвіду вирішує це через структурований контент, кастомні WYSIWYG-редактори та хмарні медіатеки.

Коли headless CMS виправдана, а коли — ні

Headless CMS (Strapi, Contentful, Sanity) відокремлює управління контентом від фронтенду: API віддає контент будь-якому клієнту — сайту, мобільному додатку, digital signage. Вибір для омніканальних проєктів і коли фронтенд на React/Vue/Next.js. Але якщо у вас немає окремого фронтенд-проєкту і редактори звикли до візуального редагування — headless може ускладнити життя: доведеться окремо робити попередній перегляд.

Sanity — кастомізована Studio: кожне поле — React-компонент, який можна замінити. Portable Text (формат для rich content) портується в будь-який рендерер. Для складних редакторських workflow — найкращий вибір. Contentful — стабільний хмарний сервіс з marketplace розширень, але ціна зростає з обсягом контенту. Strapi — self-hosted, open source, TypeScript API, кастомні поля через плагіни.

Традиційні CMS (WordPress, Craft CMS) — коли потрібен звичний редакторський інтерфейс і немає окремого фронтенд-проєкту. Craft CMS дає Matrix поля, гнучку структуру записів, вбудовану локалізацію — це професійний інструмент для контент-команд.

Як ми будуємо WYSIWYG-редактор, який не ламає верстку

Редактор — окрема інженерна задача, не просто <textarea>. Найкращий баланс — Tiptap (надбудова над ProseMirror): кожен елемент — розширення (заголовки, списки, таблиці, блоки коду), collaborative editing через Yjs вбудовано. Lexical (від Meta) — продуктивніший, але складніший у налаштуванні. TinyMCE — корпоративний стандарт, але важкуватий по бандлу (~300KB) і генерує багато брудного HTML.

Головна проблема — вставка з Word. &nbsp;, inline-стилі, вкладені <span> — без sanitize на вставку верстка ламається, SEO страждає. Ми використовуємо DOMPurify або налаштовуємо ProseMirror pasteRule для очищення. Результат — чистий HTML, який не змінюється при редизайні.

Медіатека: від завантаження до CDN

Завантажувати файли через <input type="file"> на диск сервера — антипатерн. Диск переповниться, масштабування неможливо, CDN не підключити. Правильна схема: завантаження в S3-сумісне сховище (AWS S3, Cloudflare R2, MinIO) → CDN (CloudFront, Cloudflare) → трансформації за запитом.

Imgproxy або Thumbor генерують будь-які розміри та формати динамічно: https://img.example.com/resize:800:600/format:webp/plain/s3://bucket/photo.jpg. Оригінал зберігається один раз, похідні не займають місце. Cloudflare Images — managed-сервіс.

Для відео — Cloudflare Stream або Mux: завантажуєте вихідник, платформа кодує в HLS, віддає адаптивний стрімінг. Без цього відео важить 500MB і завантажується цілком.

Що входить в розробку медіатеки

Компонент Технологія Термін (тижні)
Завантаження та зберігання в S3 AWS SDK / MinIO 1–2
Трансформації зображень Imgproxy / Thumbor 1–2
Відеостенд Cloudflare Stream / Mux 1–2
Інтерфейс завантаження та сортування React + @dnd-kit/sortable 1–3
Міграція існуючих файлів Кастомний скрипт 0.5–1

Структурований контент vs free-form HTML

Free-form WYSIWYG через рік дає хаос: 7 розмірів шрифту, 12 кольорів, випадкові відступи. Редизайн без ручного чищення неможливий. Структурований контент — замість «як воно виглядає» зберігаємо «що це є». Не <p style="font-size:24px; color:red">Важно!</p>, а тип блоку callout з параметром variant: warning. CMS зберігає структуру, фронтенд вирішує, як рендерити. Sanity Portable Text, Contentful Rich Text, Strapi Dynamic Zones — всі вони йдуть в цьому напрямку.

Чи варто впроваджувати структурований контент?

Процес роботи

  1. Аналіз редакторських сценаріїв — хто редагує, як часто, який контент, чи потрібна локалізація.
  2. Вибір CMS під сценарії, а не по трендах.
  3. Проектування контент-моделі — типи записів, поля, зв'язки.
  4. Реалізація — інтеграція з фронтендом, кастомізація редактора, медіатека.
  5. Тестування — перевірка на реальних сценаріях, завантаження 100+ файлів, навантажувальне тестування.
  6. Деплой та документація — інструкція для редакторів, опис API, доступи.

Строки та бюджет

Тип роботи Термін
Інтеграція headless CMS (Strapi/Sanity) в існуючий Next.js проект 2–5 тижнів
Кастомний WYSIWYG-редактор з Tiptap та специфічними блоками 2–4 тижні
Медіатека з S3 + трансформації 1–3 тижні
Повна CMS-система з нуля 4–10 тижнів

Бюджет розраховується індивідуально після аудиту. Зв'яжіться з нами — оцінимо ваш проєкт за один день.

Що ви отримаєте після завершення

  • Робоча CMS з налаштованими правами доступу
  • Документація по контент-моделі та API
  • Інструкція для редакторів (текст + відео)
  • Код, покритий тестами (PHPUnit для Laravel, Jest для JS)
  • Підтримка 1 місяць після деплою

Наш досвід

6 років на ринку, 40+ виконаних проєктів. Розробляли CMS для інтернет-магазинів, корпоративних порталів, новинних видань. Використовуємо ліцензійне ПЗ (sentry.io, sonarcloud) — гарантуємо якість коду.

Джерело: внутрішня статистика проєктів за 2018–2024 рр.

Детальніше про WYSIWYG-редактори читайте на Wikipedia.

Залишилися питання?

Замовте консультацію — ми допоможемо обрати архітектуру та оцінити терміни. Отримайте пропозицію протягом 2 робочих днів.