Tiptap React Editor: Як ми спростили HTML-блоки PageBuilder
Tech
Tiptap
React
Next.js
E-commerce

Tiptap React Editor: Як ми спростили HTML-блоки PageBuilder

Ми додали редактор Tiptap React до нашого ecommerce PageBuilder, щоб продавці могли створювати HTML-блоки без роботи з необробленою розміткою.

Uygar DuzgunUUygar Duzgun
Jun 17, 2026
Оновлено 23 серп. 2026 р.
8 min read

Найкраще оновлення редактора — це те, що усуває страх під час роботи з контентом.

Ми додали редактор Tiptap React до нашого ecommerce PageBuilder, тому що необроблені HTML-блоки стали надто складними для редагування. Вони працювали, але лише для людей, яким було комфортно читати розмітку. Продавець має мати змогу додати заголовок, зображення, кнопку, колонки, вкладки або вбудований Instagram, не порушуючи макет сторінки товару й не публікуючи небезпечний HTML.

Робота була виконана у гілці `codex/htmlblock-wysiwyg-editor` теми ecom. Перший коміт реалізації, `08692e2e`, додав WYSIWYG-редактор HTML-блоків. Наступні коміти вдосконалили взаємодію, перенесли підписи до системи перекладів, посилили обробку медіа та усунули дублювання зображень із медіатеки за ID.

Tiptap добре підійшов, оскільки не змушував нас переходити на закриту структуру CMS. Ми зберегли наявний HTML-контракт PageBuilder і використали Tiptap як рушій редагування.

Що ми створили

Видима функція проста: HTML-блоки PageBuilder тепер мають повноцінний редактор замість текстового поля для необробленого HTML.

Реалізація корисніша, ніж може здатися з цього речення. Редактор підтримує:

заголовки від H2 до H6
абзаци, жирний, курсивний і підкреслений текст, закреслення, код, цитати, списки, виділення та посилання
вирівнювання тексту й розміри шрифту на основі класів
CTA-кнопки, які відображаються як доступні для сканування посилання
адаптивні макети колонок
зображення з альтернативним текстом, підписами, лінивим завантаженням і вибором із медіатеки
вбудовані Instagram без перенесення тегів script у збережений контент
роздільники для контрольованого ритму макета
вкладки з двома — двадцятьма панелями
таблиці та застарілу розмітку CMS, яку потрібно зберігати для старішого контенту

Останній пункт був важливим. Це не був редактор, створений з нуля. Ecommerce-фронтенд уже містив контент у стилі Bootstrap, застарілі фрагменти CMS, зони PageBuilder, шляхи до медіа PrestaShop і правила SEO. Нам потрібен був WYSIWYG-рівень, який міг би редагувати контент, не спрощуючи наявну HTML-модель сайту.

Чому Tiptap здався простим

Налаштування Tiptap для React невелике: `useEditor`, `EditorContent` і масив розширень. StarterKit надає базові примітиви редагування, після чого можна додати потрібні продукту компоненти.

У нашому випадку набір залежностей залишався зрозумілим:

`@tiptap/core`
`@tiptap/react`
`@tiptap/starter-kit`
`@tiptap/extension-link`
`@tiptap/extension-highlight`

Цього було достатньо, щоб створити поверхню редактора, а потім додати поверх неї власні ecommerce-блоки. Ми використали `StarterKit.configure()` для стандартної поведінки редактора, вимкнули стандартну обробку посилань там, де були потрібні власні правила, а потім явно налаштували Link і Highlight.

Простота полягала не в тому, що Tiptap розв’язав усі проблеми ecommerce. Це не так. Простота була в моделі розширень. Ми могли безпосередньо описати власні вузли контенту: кнопку, зображення, застаріле зображення, вбудований Instagram, колонки, вкладки, роздільник, таблицю, розмір шрифту, стиль списку та вирівнювання тексту.

Це добре відповідає PageBuilder. Кнопка — це не просто стилізований текст. Зображення — це не просто тег `img`. Компонент вкладок має підписи, панелі, ID, активний стан і доступні ролі. Tiptap дозволив нам моделювати ці речі як контент редактора, а не намагатися визначити їх із текстового поля постфактум.

Важливим був повний цикл перетворення HTML

Чимало міграцій WYSIWYG зазнають невдачі, тому що редактор хоче один формат, а сайт відображає інший.

Ми цього не хотіли. Фронтенд уже відображає HTML-блоки на сторінках товарів, контентних сторінках, секціях головної сторінки, слотах поруч із checkout та інших зонах PageBuilder. Редактор мав завантажувати наявний HTML, дозволяти адміністратору змінювати його й зберігати HTML, який публічна вітрина могла б безпечно відобразити.

Tiptap надав нам інструменти перетворення для цього. Для панелей вкладок ми використовуємо `generateJSON()`, щоб перетворити наявний HTML на контент редактора, і `generateHTML()`, щоб перетворити вміст панелі назад на HTML. Це зберігає структуровану поверхню редагування, водночас підтримуючи публічний HTML-вивід сайту.

Це важливо і для SEO. CTA залишається посиланням. Заголовок залишається заголовком. Зображення залишається семантичною фігурою з альтернативним текстом і підписом. Вміст панелей вкладок залишається доступним для сканування. Ми не сховали ecommerce-копірайтинг усередині клієнтського віджета, який пошукові системи або допоміжні технології мають самостійно розпізнавати.

Для продавців редактор простий, а для коду — суворий

Адмін-інтерфейс приховує більшість складності.

Редактори бачать кнопки панелі інструментів, діалоги, картки макетів, поля зображень і вибір із медіатеки. Вони можуть виділити текст і використати плаваюче BubbleMenu для форматування. Вони можуть вибрати макет із двома або трьома колонками, не запам’ятовуючи класи Bootstrap. Вони можуть додати вкладки й переглянути першу панель перед збереженням.

Код залишається суворим:

посилання приймають лише дозволені протоколи
URL зображень нормалізуються перед вставленням
вбудовані Instagram зводяться до дозволених даних permalink
кількість вкладок обмежується діапазоном від 2 до 20
згенеровані ID нормалізуються до стабільних безпечних символів
стан disabled враховується через прапорець editable у Tiptap
вставлені вбудовані Instagram перетворюються на вузли редактора, а не на фрагменти скриптів

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

Безпека не була необов’язковою

Редактори форматованого тексту небезпечні, коли шлях збереження довіряє всьому, що браузер надсилає назад.

Ми додали спеціальний санітизатор форматованого тексту для публічного відображення. Він використовує DOMPurify з явним allowlist тегів і атрибутів. Санітизатор видаляє скриптову та виконувану розмітку до того, як контент потрапляє до небезпечних місць вставлення сирого HTML у React. Він також нормалізує дані вбудованого Instagram і видаляє заблоковані протоколи URL з атрибутів, що містять URL.

Тести відображення охоплюють важливі для ecommerce page builder випадки:

адаптивні колонки залишаються неушкодженими
кнопки, створені в редакторі, залишаються доступними для сканування
зображення відображаються як ліниво завантажувані семантичні фігури
роздільники та класи розміру шрифту зберігаються під час відображення
безпечні вбудовані Instagram зберігають permalink і втрачають тег script
вкладки зберігають семантику `tablist` і `tabpanel`
застарілі сітки зображень CMS зберігаються всередині вкладок
виконувана розмітка видаляється перед публічним відображенням

У цьому різниця між «ми додали WYSIWYG-редактор» і «ми можемо дозволити людям користуватися ним у production».

Історія гілки розповідає справжню історію

Перший коміт був великим: змінено 18 файлів, додано 6 282 рядки та видалено 187. Він додав залежності Tiptap до обох storefront-застосунків, компонент редактора на 3 000 рядків, понад 1 100 рядків SCSS редактора, тести відображення, елементи керування в адмінці, обробку макетів і шлях санітизації.

Потім почалося вдосконалення. `d092141d` покращив редактор HTML-блоків і взаємодію з навігацією. `320591ec` додав переклади англійською, шведською та французькою, видалив hook вибору медіа, посилив поведінку редактора й зробив вкладки гнучкішими. `2c7928b9` усунув дублювання зображень із медіатеки за ID.

Це справжній шаблон роботи над редактором. Перша версія доводить, що редактор може існувати. Наступні коміти роблять його зручним.

Де Tiptap допоміг найбільше

Tiptap допоміг у трьох місцях.

По-перше, він зробив ядро редактора непомітним. Нам не потрібно було вигадувати виділення, команди, скасування/повторення дій, поведінку клавіатури чи плаваючі меню. React-інтеграція та StarterKit надали стабільну основу.

По-друге, він дозволив моделювати ecommerce-специфічні блоки, не ховаючи їх у крихких маніпуляціях із рядками. Власні вузли та команди надали кнопкам, зображенням, колонкам, вкладкам і вбудованим елементам реальну структуру.

По-третє, він дозволив зберегти наш контракт відображення. Ми могли зберігати й відображати HTML, оскільки публічна вітрина вже залежить від HTML-блоків, водночас використовуючи структурований контент редактора всередині там, де це має сенс.

Таке поєднання трапляється рідко. Багато редакторів прості, доки вам не потрібен власний вивід. Багато власних редакторів гнучкі, доки вам не знадобиться звичайний досвід написання тексту. Tiptap займає корисну середню позицію.

Компроміс

Tiptap не усуває продуктові рішення.

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

Для редактора блогу Tiptap може бути швидким рішенням. Для ecommerce PageBuilder більшість роботи виконується навколо Tiptap: сумісність із застарілим контентом, тести відображення, робочі процеси медіа, доступність, SEO, переклади та захисні обмеження.

Це нормально. Хороший headless-редактор має надавати примітиви, а не вдавати, що ваших бізнес-правил не існує.

Мій висновок

Я знову використав би Tiptap для такого типу роботи.

Реалізація дала нам практичний редактор Tiptap React, не змусивши відмовитися від наявної системи PageBuilder. Продавці отримали безпечнішу поверхню редагування. Розробники зберегли передбачуваний HTML. Критично важливий для SEO контент залишається доступним для сканування. Вітрина не залежить від крихкого клієнтського трюку відображення.

Це стандарт, якого я хочу для ecommerce-інструментів адміністрування: прості на поверхні, суворі у вихідних даних і достатньо нудні, щоб їм можна було довіряти після першого запуску.

Джерела