Розробка WYSIWYG-редактора для CMS сайту

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

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

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

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

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

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

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

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1358
  • 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

Власний WYSIWYG-редактор ми розробляємо, коли готові інструменти не справляються з унікальними вимогами: нестандартні блоки, строгий вихідний HTML, інтеграція з бекендом CMS. Наш досвід — 10+ років і 50+ проектів — дозволяє створювати редактори під ключ за 3–12 тижнів. Ми гарантуємо документацію, навчання та підтримку після здачі.

Готові редактори (TinyMCE, CKEditor) часто мають надлишкову функціональність або, навпаки, не дозволяють додати специфічні блоки: відео з кастомного плеєра, інтерактивні таблиці, вбудовування із зовнішніх сервісів. Крім того, вони генерують брудний HTML, який складно парсити на бекенді. Кастомний редактор дає повний контроль над моделлю даних і вихідним кодом.

Ми проектуємо редактор під конкретну CMS: Laravel, WordPress, Django або кастомне рішення. Контент зберігаємо в JSONB полях бази даних — це гнучко та індексується. На виході — швидкий, передбачуваний редактор з контекстним тулбаром, slash-командами та перетягуванням блоків.

Сценарії для кастомного WYSIWYG-редактора

Свій редактор пишуть, коли жодне готове рішення не закриває всі вимоги. Типові сценарії:

  • Нестандартні блоки: кастомні галереї, інтерактивні схеми, вбудовування сторонніх сервісів через iframe.
  • Чистий HTML: потрібен строгий вихідний код без зайвих обгорток, наприклад, для подальшої конвертації в PDF або e-mail.
  • Глибока інтеграція: редактор повинен зберігати дані безпосередньо в CMS, працювати з медіатекою, підтримувати права доступу.
  • Продуктивність: при сотнях блоків на сторінці готові редактори гальмують — потрібна віртуалізація та ліниве завантаження.

Який двигун вибрати: ProseMirror, Slate чи Lexical?

Писати редактор на голому contenteditable — шлях до нескінченних багів. Вибір стоїть між трьома зрілими двигунами:

Двигун Гнучкість Продуктивність Підтримка React Складність освоєння
ProseMirror Висока Висока Через Tiptap Висока
Slate.js Середня Середня Нативна Середня
Lexical Висока Дуже висока Нативна Середня

ProseMirror дає максимальний контроль над моделлю даних — його використовують, наприклад, у New York Times. Slate.js кращий для React-проектів, де важлива швидкість розробки. Lexical від Meta — найпродуктивніший, але спільнота ще невелика.

Як побудувати модель даних для редактора?

Редактор повинен працювати з чіткою схемою. Два популярних підходи: Flat JSON (список блоків) та Дерево (вкладена структура).

Приклад Flat JSON (стиль Editor.js):

{
  "blocks": [
    { "id": "abc123", "type": "header", "data": { "text": "Заголовок", "level": 2 } },
    { "id": "def456", "type": "paragraph", "data": { "text": "Текст параграфа" } },
    { "id": "ghi789", "type": "image", "data": { "url": "/uploads/photo.jpg", "caption": "Підпис" } }
  ],
  "version": "2.28.0"
}

Приклад дерева (ProseMirror/Tiptap):

{
  "type": "doc",
  "content": [
    {
      "type": "heading",
      "attrs": { "level": 2 },
      "content": [{ "type": "text", "text": "Заголовок" }]
    },
    {
      "type": "paragraph",
      "content": [
        { "type": "text", "text": "Звичайний " },
        { "type": "text", "marks": [{ "type": "bold" }], "text": "жирний" },
        { "type": "text", "text": " текст" }
      ]
    }
  ]
}

У PostgreSQL дані зберігаються в jsonb з GIN-індексом для повнотекстового пошуку. Кожен тип блоку — окрема React-компонента з режимами перегляду та редагування. Реєструємо блоки через плагінну систему:

interface BlockPlugin<T = Record<string, unknown>> {
  type: string;
  label: string;
  icon: React.ReactNode;
  defaultData: T;
  render: (data: T, ctx: RenderContext) => React.ReactNode;
  edit: (data: T, onChange: (data: T) => void) => React.ReactNode;
  validate?: (data: T) => ValidationError[];
  toHTML?: (data: T) => string;
}

Контекстний тулбар, slash-команди та drag-and-drop

Тулбар з'являється лише при виділенні тексту — не займає місце і не відволікає. Реалізуємо плаваючу панель через FloatingToolbar з кнопками жирності, курсиву, посилання.

Slash-команди — стандарт для блочних редакторів: введення / відкриває меню вибору блоку. Фільтрація за назвою прискорює роботу.

Drag-and-drop сортування блоків реалізоване через @dnd-kit/core. Блоки перетягуються без втрати контенту.

Як працює історія змін?

class EditorHistory {
  private undoStack: EditorState[] = [];
  private redoStack: EditorState[] = [];
  private maxSize = 100;

  push(state: EditorState) {
    this.undoStack.push(structuredClone(state));
    if (this.undoStack.length > this.maxSize) this.undoStack.shift();
    this.redoStack = [];
  }

  undo(current: EditorState): EditorState | null {
    if (this.undoStack.length === 0) return null;
    this.redoStack.push(structuredClone(current));
    return this.undoStack.pop()!;
  }

  redo(current: EditorState): EditorState | null {
    if (this.redoStack.length === 0) return null;
    this.undoStack.push(structuredClone(current));
    return this.redoStack.pop()!;
  }
}

Для великих документів використовуємо імутабельні структури (Immer) для економії пам'яті.

Автозбереження — через дебаунс 2 секунди після останньої зміни. Статус відображається в інтерфейсі: «Збережено», «Збереження...», «Є зміни».

Рендеринг на фронтенді сайту

JSON редактора рендериться на публічній частині сайту. Два підходи:

  1. SSR через React — дані передаються в ті ж компоненти блоків, що й у редакторі. Ідеально для Next.js.
  2. Серверний рендеринг — на PHP або Node.js парсимо JSON і генеруємо HTML безпосередньо, без React.
Підхід Продуктивність Складність Гнучкість
SSR з React Середня Середня Висока
Серверний рендеринг Висока Висока Середня

Приклад рендерера на Laravel:

class BlockRenderer
{
    protected array $renderers = [];

    public function register(string $type, callable $renderer): void
    {
        $this->renderers[$type] = $renderer;
    }

    public function render(array $blocks): string
    {
        return collect($blocks)
            ->map(fn($block) => ($this->renderers[$block['type']] ?? fn() => '')($block['data']))
            ->implode("\n");
    }
}

Робота з медіа та продуктивність

Редактор інтегрується з медіатекою CMS. Зображення завантажуються через drag-and-drop прямо в блок — прогрес-бар показує статус. Для великих документів (сотні блоків і десятки зображень) вмикаємо віртуалізацію: рендеримо лише видимі блоки плюс буфер, інші замінюємо плейсхолдерами. Використовуємо react-window або @tanstack/virtual.

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

  • Аналіз вимог і проектування моделі даних
  • Розробка ядра редактора та системи плагінів
  • Реалізація типових і кастомних блоків
  • Інтеграція з CMS через REST API або пряму роботу з БД
  • Налаштування автозбереження, історії, медіатеки
  • Тестування та налагодження
  • Створення документації та навчання редакторів
  • Гарантійна підтримка 12 місяців

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

Орієнтовні терміни:

  • MVP: 3–4 тижні
  • Повноцінний редактор: 8–12 тижнів
  • Складні проекти з унікальними блоками: до 16 тижнів

Вартість розраховується індивідуально залежно від складності. Конкретну цифру називаємо після аудиту вимог.

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

  • 10+ років досвіду в розробці редакторів для медіа та корпоративних сайтів
  • 50+ проектів — від невеликих блогів до великих порталів
  • Прозорий процес: кожні 2 тижні демонструємо проміжні результати
  • Гарантія 12 місяців і безкоштовна підтримка після запуску

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

Розробка систем керування контентом: 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 робочих днів.