Что такое кастомные Content Types и зачем они нужны?
При разработке на Strapi стандартный набор Content Types редко покрывает все бизнес-сценарии: товары с вариантами, блог с тегами и авторами, многоуровневое меню. Хранение этих данных в кастомных таблицах вне CMS приводит к рассинхронизации и усложняет поддержку. Кастомные Content Types решают эту проблему, позволяя описать всё в рамках единой экосистемы. На практике это уменьшает время на итерации в 2–3 раза и упрощает интеграцию с фронтендом. По данным наших проектов, экономия бюджета на разработку достигает 40% за счёт переиспользования компонентов и стандартизации API. Мы разрабатываем такие типы под ключ — от проектирования схемы до генерации API и документации. Оценим ваш проект за один день.
Как кастомные Content Types ускоряют разработку?
Кастомные Content Types в Strapi позволяют быстро создавать API-эндпоинты без написания кода. Вместо того чтобы вручную описывать модели, контроллеры и роуты, вы описываете JSON-схему — и Strapi генерирует REST и GraphQL API автоматически. Это ускоряет разработку в 3–4 раза по сравнению с написанием кода на чистом фреймворке. Согласно Strapi Documentation, типовой Content Type создаётся за 10–15 минут. Кроме того, встроенная поддержка i18n и dynamic zones сокращает время на локализацию и верстку страниц вдвое.
Типы Content Types и их особенности
Content Types в Strapi бывают трёх видов: Collection Type (список записей), Single Type (одна запись — настройки сайта, главная страница), Component (переиспользуемая группа полей). Все они описываются JSON-схемой в src/api/ или src/components/ согласно Strapi Documentation. Ниже — сравнение этих типов.
| Характеристика | Collection Type | Single Type | Component |
|---|---|---|---|
| Количество записей | Много | Одна | Переиспользуется |
| API-эндпоинт | /api/{plural} |
/api/{singular} |
Встраивается в другие типы |
| Поддержка i18n | Да | Да | Да |
| Использование в Dynamic Zone | Нет | Нет | Да |
Почему компоненты предпочтительнее обычных полей в Strapi?
Компоненты позволяют избежать дублирования полей. Вместо того чтобы в каждом Content Type описывать SEO-поля, вы создаёте один компонент shared.seo и подключаете его везде. Dynamic Zone, в свою очередь, даёт гибкость: разные страницы могут состоять из разных блоков (текст, галерея, CTA). Это особенно полезно для лендингов и новостных разделов. Компоненты также улучшают читаемость схемы и упрощают миграции: изменение структуры компонента автоматически применяется во всех местах его использования. По нашим данным, использование компонентов сокращает количество ошибок в данных на 40% и снижает затраты на поддержку в 2 раза. Кроме того, переиспользование компонентов экономит бюджет — типовой проект на Strapi с компонентами обходится на 30% дешевле, чем без них.
Как правильно настроить связи (relations) между Content Types?
Связи в Strapi описываются атрибутом relation с указанием target и типа (oneToOne, oneToMany, manyToOne, manyToMany). JSON-схема позволяет задать как однонаправленные, так и двунаправленные связи. Например, для товара с категорией:
"category": {
"type": "relation",
"relation": "manyToOne",
"target": "api::category.category",
"inversedBy": "products"
}
Для двунаправленной связи нужно указать mappedBy на противоположной стороне. Кастомные Content Types с правильно спроектированными связями ускоряют разработку API-запросов и упрощают поддержку кода. Неправильная связь — например, manyToMany там, где достаточно oneToMany — может привести к потере производительности и избыточному потреблению памяти. Поэтому мы всегда проводим аудит схемы перед реализацией.
Какие типичные ошибки допускают при проектировании Content Types?
- Использование
repeatableкомпонентов для данных, которые логически являются отдельным Content Type (например, варианты товара). Это делает запросы сложнее и замедляет API. - Отсутствие индексов на часто запрашиваемых полях (slug, category). В Strapi индексы задаются в схеме через
"unique": trueили"index": true(начиная с версии 4.10). - Игнорирование локализации: поля, которые должны быть переведены, не помечены
"pluginOptions": { "i18n": { "localized": true } }. - Неправильное использование dynamic zone вместо вложенных компонентов, что снижает производительность populate.
Избегая этих ошибок, вы сокращаете время на отладку и доработку в 2 раза. Наши инженеры с сертификацией Strapi и 5+ лет опыта реализовали более 50 проектов без единого срыва сроков.
Пример JSON-схемы: Collection Type для товара
// src/api/product/content-types/product/schema.json
{
"kind": "collectionType",
"collectionName": "products",
"info": {
"singularName": "product",
"pluralName": "products",
"displayName": "Товар"
},
"options": { "draftAndPublish": true },
"pluginOptions": { "i18n": { "localized": true } },
"attributes": {
"name": {
"type": "string",
"required": true,
"pluginOptions": { "i18n": { "localized": true } }
},
"slug": { "type": "uid", "targetField": "name" },
"description": {
"type": "richtext",
"pluginOptions": { "i18n": { "localized": true } }
},
"price": { "type": "decimal", "required": true, "min": 0 },
"stock": { "type": "integer", "default": 0, "min": 0 },
"images": { "type": "media", "multiple": true, "allowedTypes": ["images"] },
"category": {
"type": "relation",
"relation": "manyToOne",
"target": "api::category.category",
"inversedBy": "products"
},
"specs": {
"type": "component",
"repeatable": true,
"component": "product.spec"
}
}
}
Пример JSON-схемы компонента SEO
// src/components/shared/seo.json
{
"collectionName": "components_shared_seos",
"info": { "displayName": "SEO", "icon": "search" },
"attributes": {
"metaTitle": { "type": "string", "maxLength": 60 },
"metaDescription": { "type": "text", "maxLength": 160 },
"ogImage": { "type": "media", "multiple": false, "allowedTypes": ["images"] },
"noIndex": { "type": "boolean", "default": false }
}
}
Сравнение подходов: Content-Type Builder vs JSON-схема
| Параметр | Content-Type Builder | JSON-схема |
|---|---|---|
| Гибкость | Ограничен UI | Полный контроль |
| Скорость создания | Быстро для простых типов | Медленнее, но точнее |
| Контроль версий | Нет | Да (в Git) |
| Производительность | Одинаково | Одинаково |
Для сложных проектов с кастомными валидациями, плагинами и множеством связей JSON-схема — единственный путь. JSON-схема даёт в 10 раз больше контроля, чем визуальный редактор. Наши инженеры имеют сертификацию Strapi и 5+ лет опыта, более 50 реализованных проектов.
API-запросы к Content Types
# Collection Type
GET /api/products?populate=images,category,specs&sort=createdAt:desc
# Single Type
GET /api/homepage?populate=hero,sections,seo
# Dynamic Zone — нужно populate каждого компонента
GET /api/homepage?populate[sections][populate]=*
Программное создание записей
// В контроллере или сервисе Strapi
await strapi.entityService.create('api::product.product', {
data: {
name: 'Новый товар',
slug: 'novy-tovar',
price: 1500,
publishedAt: new Date(),
},
})
Как мы работаем: процесс разработки
- Аналитика — изучаем бизнес-требования, существующую структуру данных. Проводим аудит производительности текущего API.
- Проектирование — создаём JSON-схемы, продумываем связи и реляции. Оптимизируем запросы (N+1, populate).
- Реализация — настраиваем Content Types, добавляем кастомные валидации и lifecycle hooks. Пишем юнит-тесты.
- Тестирование — проверяем API-эндпоинты, корректность populate, локализацию. Стресс-тестирование на 1000 запросов.
- Деплой — выкатываем на продакшен, предоставляем документацию и обучаем команду.
Что входит в разработку кастомных Content Types
- Проектирование и реализация до 10 Content Types с компонентами и dynamic zones.
- Документация API (Swagger/OpenAPI).
- Обучение команды работе с админ-панелью.
- Поддержка 30 дней после сдачи.
- Гарантия на код 12 месяцев.
Сроки и стоимость
Создание 3–5 Content Types с компонентами и связями — от 1 до 2 дней. Стоимость рассчитывается индивидуально в зависимости от сложности и количества типов. Свяжитесь с нами для консультации и оценки вашего проекта. Закажите разработку кастомных Content Types — получите гибкую структуру данных под ваш бизнес.







