В Strapi удобно верстать страницы как в конструкторе — мы об этом уже писали в материале про корпоративный конструктор на Dynamic Zones. Но у редакции есть другая, менее очевидная боль: не лендинги, а обычные статьи для блога и редакционного контента, в которые постоянно надо вставлять «читать также», расширенные цитаты, CTA, иллюстрации, иногда — целые подборки. С Rich Text трудно добиться расширяемости, а схему с десятками опциональных полей сложно поддерживать и заполнять. В этой статье разберём, как решить именно редакторский сценарий на динамических зонах Strapi: какие компоненты заводить, как сделать админку удобной и что потом с этим делать на фронте.
Материал подготовлен по выступлению техлида Work Solutions на WS-митапе. Полную запись выступления можно посмотреть в конце статьи.
Что мы сначала сделали через шаблоны и почему это было временным решением
Динамические зоны появились в Strapi еще в бета-версии. Это не новая функциональность, как иногда думают разработчики. Технология была заложена в архитектуру фреймворка с самого начала, но долгое время оставалась недооцененной сообществом. В сценариях «собираем любой лендинг» их использовали раньше, а вот в блогах и редакционных разделах — почти нет: редакциям долгое время хватало Rich Text.
Причина непопулярности проста: разработчики привыкли к странично-шаблонным CMS. В WordPress, Drupal и Joomla есть типы и поля, но на практике все часто сводится к единому полю с WYSIWYG-редактором. Strapi предлагает иной подход, который требовал изменения мышления при проектировании контентных структур. Подробно про то, как Strapi эволюционирует из «просто админки» в полноценный фреймворк, мы разбирали в материале «Strapi: от админки до fullstack-фреймворка».
Перед командой Work Solutions стояла конкретная задача: создать блог для корпоративного сайта и поддерживать внутри разные по структуре материалы. Казалось бы, стандартная задача с очевидным решением. Были два варианта подходов к реализации.
Первый вариант — классический путь с жесткой структурой полей. Создать фиксированную схему статьи и работать в ее рамках. Второй — использовать динамические возможности Strapi для создания гибкой системы контента.
Классическая структура статьи
Стандартный набор полей для статьи выглядит предсказуемо. Title для заголовка, image для превью-изображения, announce для текста анонса, author для связи с автором, category для категоризации, tags для тегов, и главное поле — content для основного текста статьи.
Strapi позволяет реализовать поле content через Rich Text. Структура получается жестко описанной, без непредсказуемых поведений. Данные легко типизировать, можно ожидаемым образом получить их через API. Никаких неожиданностей при работе с такой структурой не возникает.
Пример классической модели статьи в Strapi: заголовок, анонс, дата, превью, автор, категория и одно большое поле контента
Проблемы начинаются при появлении требований добавить в контент статьи кастомные компоненты. Например, блок «Читать также» со ссылкой на другую статью. Rich Text и Markdown предоставляют возможности форматирования текста, но вставка специфических интерактивных компонентов через них невозможна.
Попытки решения в рамках жесткой структуры
Как реализовать вставку кастомных компонентов в рамках жесткой структуры? Первая мысль: использовать HTML в Rich Text редакторе. Технически возможно, но требует от контент-менеджеров знания HTML и создает риски с безопасностью и консистентностью оформления.
Второй вариант: добавить в структуру статьи дополнительные поля для каждого возможного компонента. Поле для связи с рекомендуемой статьей, поле для расширенной цитаты, поле для CTA-блока. При наличии десятков типов компонентов структура статьи превращается в набор опциональных полей, большинство из которых не используется в конкретной статье.
Редакционный блок «Читать также» на фронте — пример интерактивного модуля, ради которого неудобно плодить десятки опциональных полей
Такой подход засоряет схему данных ненужными полями. Поля для динамического контента не имеют отношения к самой сущности статьи, они нужны только в определенных ситуациях для специфического отображения.
Решение через шаблонные строки
В Work Solutions пошли путем добавления шаблонных строк в контент. В текст Rich Text редактора вставлялась жестко заданная структура, например, для блока «Читать также».
На уровне пререндера на фронтенде эта строка обрабатывалась, преобразовывалась в React-компонент и вставлялась в DOM-дерево. Парсер искал паттерны шаблонов в тексте и заменял их на соответствующие компоненты.
Так выглядело временное решение: редактор вставляет служебный маркер в Rich Text, а фронтенд уже подменяет его на компонент
Подход имел свои преимущества. Возможность расширения: добавление нового типа компонента требовало только обновления парсера. Легкая поддержка с точки зрения редактирования существующих блоков. Структура статьи оставалась чистой, без дополнительных полей.
Существенный минус заключался в необходимости документации. Новый разработчик на проекте не мог интуитивно понять, какие шаблоны поддерживаются и какой у них синтаксис. Документацию нужно было не только написать, но и постоянно поддерживать в актуальном состоянии. На практике, контент-менеджерам было проще копировать сниппеты из уже опубликованных статей, что при невнимательности могло их ломать, например если менеджер нажимал ctrl-x вместо ctrl-с и применял изменения перепутав активную вкладку.
Система работала довольно долго без критических проблем. Но существовало более элегантное и нативное для Strapi решение.
Динамические зоны как архитектурное решение
Динамическая зона в Strapi — это участок контента внутри типа (статьи, страницы, товара), куда редактор может по очереди добавлять только разрешенные для этого типа блоки. Strapi при этом хранит всё как упорядоченный массив компонентов с указанием их типа (__component) и полей. За счет этого меняется не только содержание, но и сама структура страницы, без новых полей в модели и без доработки фронтенда под каждую мелочь. В редакционных разделах это дает возможность собирать разные по длине и насыщенности статьи, не раздувая схему.
Проектирование компонентов
Первый шаг — определение набора компонентов для статьи. Для упрощения в примере Work Solutions ограничились четырьмя базовыми типами: параграф текста, изображение с подписью, цитата с расширенными полями, блок call-to-action.
Каждый компонент представляет собой независимую структуру данных со своим набором полей. Это не просто разметка или шаблон, а полноценная модель данных.
Создание компонентов в Strapi
В админке Strapi компоненты создаются через интерфейс Content-Type Builder. Они группируются, и в данном случае все компоненты статьи для корпоративного блога объединены в группу article. Группировка критически важна при большом количестве таких элементов в системе.
Компонент текста имеет единственное поле content с типом Rich Text. Это позволяет сохранить возможности форматирования текста внутри отдельных параграфов.
Компонент цитаты содержит три поля: text для самой цитаты, author для автора, source для источника. Это принципиальное отличие от стандартной цитаты в Rich Text, где доступны только текст и автор.
Компонент изображения включает поле для медиафайла и поле caption для подписи. Опять же, больше возможностей чем стандартная вставка изображения в Rich Text.
Компонент call-to-action самый сложный: содержит поля для заголовка, описания, текста кнопки, URL и стиля оформления.
Структура статьи с динамическими зонами
После создания компонентов обновляется структура самой статьи. Поля, описывающие сущность — title, slug, author, announcement, preview image — остаются жесткими. Это метаданные статьи, которые не меняются в зависимости от контента.
Для самого контента создается динамическая зона. При создании зоны указывается, какие блоки могут в ней использоваться. В случае статьи это, например, могут быть text, quote, image и call-to-action компоненты.
Принципиальное разделение: жесткие поля описывают доменную сущность, динамическая зона содержит данные для отображения, которые не относятся к самой сущности.
Работа контент-менеджера с динамическими зонами
После настройки структуры контент-менеджер получает интуитивный интерфейс для работы с контентом. В разделе динамической зоны доступна кнопка Add component, при нажатии на которую появляется список доступных компонентов.
Добавление и настройка компонентов
Контент-менеджер выбирает нужный компонент, например Text. Компонент добавляется в зону и становится доступным для редактирования. Заполняется поле content через привычный Rich Text редактор.
Далее можно добавить компонент изображения. Загружается файл, добавляется подпись. Затем цитата — вводится текст, указывается автор и источник. Порядок компонентов меняется простым перетаскиванием через drag-and-drop.
Навигация по компонентам
При большом количестве компонентов в статье навигация становится проблемой. Strapi решает это через систему лейблов. Для каждого блока выводится краткая информация, помогающая идентифицировать его без раскрытия.
У компонента call-to-action выводится текст кнопки. У изображения — значение alt-текста. Проблема возникает с компонентами, содержащими Rich Text. Strapi не может вывести форматированный текст в качестве лейбла.
Для решения проблемы нужно добавить приватное поле _label с типом short string. Это поле используется только для отображения в админке и не попадает в API. Контент-менеджер заполняет его кратким описанием компонента для удобной навигации.
Практический пример добавления компонента
Рассмотрим добавление компонента «Читать также». Контент-менеджер добавляет компонент, вводит заголовок «Читать также», выбирает связанную статью через поле relation.
После сохранения компонент можно перемещать по контенту. Например, поднять на один абзац выше. Strapi автоматически обновляет порядок компонентов в массиве.
Получение и обработка данных на фронтенде
На фронтенд данные динамической зоны приходят в виде массива объектов. Структура предсказуема: каждый объект имеет поля id и __component, остальные поля зависят от типа компонента. В Strapi 5 для динамических зон в продакшене часто требуется явно указывать populate для нужных полей, чтобы на фронт уходили не только ссылки, но и сами данные вложенных компонентов.
Структура данных
Пример ответа API для статьи с динамическими зонами:
Фрагмент ответа Strapi: базовые поля статьи плюс массив компонентов динамической зоны с указанием их типа
Структура максимально динамичная, но предсказуемая. В поле content могут прийти только те элементы, которые были определены при создании динамической зоны.
Рендеринг на фронтенде
В Next.js приложении создается компонент для рендера динамической зоны, в нашем случае он называется DynamicZone. Классический подход — использование switch-case по полю «__component»:
Фронтенд-рендер динамической зоны: по значению __component выбирается соответствующий React-компонент
Каждый элемент данных на стороне Strapi имеет соответствующий визуальный модуль для отображения в React. Разделение четкое: сущности Strapi отвечают за структуру данных, а модули React — за представление.
Преимущества перед Rich Text
Почему не использовать встроенные возможности Rich Text для тех же цитат? Rich Text позволяет вставить цитату, но только с базовыми полями, такими как: текст и автор. Если дизайн требует отображение источника, даты, ссылки на оригинал, то Rich Text не справится.
Динамические зоны дают полный контроль над структурой каждого структурного элемента. Можно добавить любые поля, настроить валидацию, создать связи с другими сущностями.
Технические ограничения и рекомендации
Strapi накладывает ряд ограничений на использование динамических зон. Часть из них — жесткие технические лимиты, часть — рекомендации для оптимальной работы. Важно понимать разницу по сценариям: для лендингов можно позволить себе почти полностью динамическую страницу, потому что ее собирают реже и обычно — продвинутые редакторы; для блога и редакционного контента лучше придерживаться комбинированной схемы — жесткие поля + одна динамическая зона под тело. Так и админка остаётся понятной, и API — предсказуемым.
Количество компонентов в зоне
Strapi рекомендует не использовать более 10 компонентов в одной динамической зоне. Однако это не техническое ограничение, поэтому можно добавить и 20, и 30 компонентов. Ограничение связано с удобством использования и производительностью интерфейса.
В проекте с фильтрами товаров, о котором рассказали в предыдущей статье, использовалось до 20 компонентов в одной зоне. Система работала без проблем, но навигация по структурным элементам становилась затруднительной.
Вложенность компонентов
Технически действует жесткое ограничение: не более трех уровней вложенности структурных элементов друг в друга. Элемент может содержать другой компонент, тот, в свою очередь, — третий, но не глубже.
Ограничение можно обойти через прямое редактирование структуры данных в коде, минуя админку. Но Strapi не гарантирует корректную работу при превышении лимита вложенности.
Динамические зоны внутри динамических зон
Еще одно ограничение: нельзя вкладывать динамические зоны в динамические зоны через админку. Иногда такая возможность напрашивается, например, для создания сложных лендингов с вложенными секциями.
Технически это тоже можно обойти через код. На практике работает, но возникают проблемы с переиспользованием данных при запросах к БД. Могут быть проблемы с populate и производительностью.
Полностью динамические коллекции
Теоретически можно создать коллекцию, состоящую только из динамической зоны, без жестких полей. На практике это создает множество проблем:
- производительность запросов. Получение и фильтрация данных из полностью динамических коллекций требует сложных SQL-запросов с множественными JOIN;
- невозможность определить обязательные поля. Из коробки нельзя потребовать наличие конкретного блока в каждой записи; можно помечать обязательные поля внутри компонентов. Жёсткие правила вида «обязан быть компонент X» или «ровно один SEO-блок» достигаются кастомной валидацией;
- сложность работы с данными на фронтенде. Без гарантированной структуры приходится делать множество проверок на наличие данных.
Правильный подход к использованию
Оптимальная стратегия для блога и редакционного контента: комбинирование жестких полей и динамических зон. Доменная модель описывается через обычные поля. Все, что относится к сущности как таковой, должно быть жестким полем.
Например, для товара это название, цена, артикул, категория, базовое изображение. Эти данные всегда должны присутствовать, они описывают сам товар.
Динамические зоны используются для контента, который относится к отображению, но не к сущности. Описание товара, галерея дополнительных изображений, блоки с преимуществами — все это может быть динамическим.
Интеграция с поиском и индексацией
При использовании динамических зон для основного контента внутри корпоративного блога возникает вопрос полнотекстового поиска. Как индексировать контент, разбитый на множество структурных блоков?
Стандартные поисковые решения ожидают текст в виде единого поля. Elasticsearch, Algolia, MeiliSearch — все они работают с документами, где контент представлен строкой.
Динамические зоны хранятся в БД как JSON. Прямой поиск по такой структуре неэффективен и не даст релевантных результатов.
В Work Solutions проблему решили через хуки жизненного цикла Strapi. При создании или обновлении статьи срабатывает хук afterCreate/afterUpdate.
В хуке происходит обход всех структурных блоков динамической зоны. Из каждого блока извлекается текстовое содержимое. Компонент text отдает свой content — контент, quote — текст цитаты, image — alt-текст и caption.
Собранные тексты объединяются в единую строку. Эта строка отправляется в поисковой движок для индексации. Таким образом, поиск работает с полным текстом статьи, хотя в БД он хранится фрагментировано.
Требования к дизайну и проектированию
Для эффективной работы с динамическими зонами критически важно правильное проектирование на этапе дизайна. Решения, принятые дизайнером, напрямую влияют на сложность реализации и удобство работы контент-менеджеров.
Первый вопрос: из каких блоков будет состоять система? Нужно определить базовые компоненты, которые станут строительными блоками для страниц.
Базовые компоненты должны быть атомарными, то есть выполнять одну конкретную функцию. Текстовый блок, изображение, видео, кнопка. Из них собираются более сложные компоненты.
Сложные компоненты — это комбинации базовых. Карточка товара может состоять из изображения, заголовка, описания и кнопки. Но реализовывать её лучше как единый элемент, а не как череда базовых блоков.
Второй критический вопрос: какие структурные блоки можно использовать вместе? Не все блоки хорошо сочетаются визуально. Например, два компонента галереи подряд могут создавать визуальный конфликт. Или блок с фоновым видео после блока с параллакс-эффектом может вызвать проблемы с производительностью.
На уровне дизайна нужно продумать и задокументировать правила сочетаемости. Какие компоненты можно ставить рядом, какие требуют разделителя, какие вообще несовместимы.
Часть этих правил касается и отступов. У каждого структурного блока могут быть свои margin и padding. При произвольной комбинации отступы могут складываться или конфликтовать. Поэтому сетку отступов лучше стандартизировать на уровне дизайн-системы. Все блоки должны следовать единой сетке. Идеально, когда отступы настраиваются не у компонентов, а у контейнера динамической зоны.
Спроектированы они должны быть с учетом всех размеров экранов. Особенно это важно для мобильных устройств. То, что хорошо выглядит в десктопной версии (текст слева, изображение справа), может требовать изменения порядка на мобильных. Нужно заранее определить правила адаптации для каждого компонента.
И наконец, добавление новых структурных элементов тоже должно идти по процессу: новый блок должен соответствовать принятой дизайн-системе, не ломать существующие правила сочетаемости и сопровождаться обновлением документации.
Практические рекомендации по внедрению
На основе опыта Work Solutions и других проектов сформировался набор проверенных практик для работы с динамическими зонами.
Начинайте с малого. Не пытайтесь сразу создать универсальную систему компонентов для всего сайта. Начните с одной сущности — например, статей блога. Создайте 4-5 базовых блока, обкатайте процесс. После стабилизации первой реализации расширяйте систему. Добавляйте новые блоки по мере необходимости, а не «про запас».
Хорошая иллюстрация того, как быстро можно стартовать на Strapi, — наш кейс: портал за месяц усилиями одного фронтенд-разработчика.
Группируйте компоненты. При росте количества структурных блоков обязательно используйте группировку. Создавайте отдельные группы для разных типов контента: article для статей блога, landing для промо-страниц, product для карточек, категорий. Группировка облегчает навигацию в админке и помогает контент-менеджерам быстрее находить нужные компоненты.
Используйте приватные поля. Для улучшения UX админки добавляйте приватные поля _label или _description. Они помогают идентифицировать компоненты в свернутом виде. Особенно это важно для компонентов с Rich Text контентом, где Strapi не может автоматически сгенерировать лейбл.
Документируйте компоненты. Создайте внутреннюю документацию по каждому структурному блоку. Опишите назначение, поля, правила использования, примеры. Документация должна быть доступна контент-менеджерам прямо из админки. Можно добавить ссылку на документацию в описание блока.
Версионируйте компоненты. При изменении структуры компонента не модифицируйте существующий, а создайте новую версию. Например, article.quote и article.quote_v2. Это позволит постепенно мигрировать контент без поломки существующих страниц.
Мониторьте производительность. Регулярно проверяйте производительность запросов к динамическим зонам. Используйте populate выборочно, только для нужных полей. При большом количестве компонентов рассмотрите кеширование на уровне API или CDN.
Обучайте контент-менеджеров. Проведите обучение для всех, кто будет работать с динамическими зонами. Покажите возможности, объясните ограничения, дайте best practices. Создайте чек-листы для типовых задач: как создать статью, как добавить галерею, как вставить CTA-блок.
Выводы и рекомендации
Динамические зоны Strapi — мощный инструмент для создания гибких контентных структур. Технология дает редакции свободу, не распиливая модель данных на десятки опциональных полей и не придумывая собственный синтаксис в тексте. Они позволяют собирать одну и ту же сущность (статью, страницу услуги, товар) из разных по структуре блоков и при этом оставаться в пределах предсказуемого API.
Технические ограничения существуют, но они не критичны при грамотном проектировании. Важно заранее определить набор допустимых компонентов, правила их сочетания и границу между «жесткими» полями и динамическим контентом и не пытаться решать динамическими зонами всё подряд.
Наш опыт в Work Solutions и проекты клиентов показывает эффективность такого подхода. Динамические зоны используются в продакшене для блогов, лендингов, каталогов товаров, личных кабинетов. В материале «как начать создавать приложение на Strapi» мы показывали, как быстро поднять приложение и модель данных — здесь речь уже про следующую стадию, когда контентом начинают активно пользоваться редакторы. А в кейсе с интернет-магазином на Strapi и Next.js мы разбирали платформу как опору для e-commerce. В этой статье фокус именно на редакторском сценарии и поддерживаемости.
Технология продолжает развиваться. Strapi 5 принес улучшения, которые закрывают многие текущие ограничения. Сообщество активно создает плагины и расширения.
Для команд, работающих со Strapi, динамические зоны — это must have технология. Инвестиция времени в изучение и внедрение окупается уже на первом проекте. Дальнейшее использование приносит только выгоду — ускорение разработки, упрощение поддержки, довольные контент-менеджеры.








