Кастомные компоненты в Strapi
Компоненты Strapi — переиспользуемые группы полей. Компонент может быть вложен в collection type, single type или другой компонент. Поддерживает два режима: одиночный (группа полей) и repeatable (массив объектов).
Структура компонента
src/components/
├── shared/ # Категория компонентов
│ ├── seo.json
│ ├── button.json
│ └── link.json
├── sections/
│ ├── hero.json
│ ├── text-block.json
│ └── gallery.json
└── product/
├── spec.json
└── variant.json
Компонент кнопки (CTA)
// src/components/shared/button.json
{
"collectionName": "components_shared_buttons",
"info": { "displayName": "Кнопка", "icon": "cursor" },
"attributes": {
"label": { "type": "string", "required": true },
"url": { "type": "string" },
"page": { "type": "relation", "relation": "oneToOne", "target": "api::page.page" },
"variant": {
"type": "enumeration",
"enum": ["primary", "secondary", "outline"],
"default": "primary"
},
"openInNewTab": { "type": "boolean", "default": false }
}
}
Секция Hero
// src/components/sections/hero.json
{
"collectionName": "components_sections_heroes",
"info": { "displayName": "Hero секция" },
"attributes": {
"title": { "type": "string", "required": true },
"subtitle": { "type": "text" },
"background": { "type": "media", "multiple": false, "allowedTypes": ["images"] },
"cta": { "type": "component", "component": "shared.button", "repeatable": false }
}
}
Spec (характеристика товара) — repeatable
// src/components/product/spec.json
{
"collectionName": "components_product_specs",
"info": { "displayName": "Характеристика" },
"attributes": {
"name": { "type": "string", "required": true },
"value": { "type": "string", "required": true },
"unit": { "type": "string" }
}
}
Использование в схеме товара:
"specs": {
"type": "component",
"repeatable": true,
"component": "product.spec",
"min": 0,
"max": 20
}
Dynamic Zone — выбор компонентов на лету
// В схеме страницы:
"body": {
"type": "dynamiczone",
"components": [
"sections.hero",
"sections.text-block",
"sections.gallery",
"sections.cta-banner"
]
}
API-запрос с динамической зоной:
GET /api/pages/about?populate[body][populate]=*
Рендеринг Dynamic Zone в Next.js:
const sectionComponents = {
'sections.hero': HeroSection,
'sections.text-block': TextBlock,
'sections.gallery': Gallery,
'sections.cta-banner': CTABanner,
}
export const DynamicZone = ({ body }: { body: any[] }) => {
return (
<>
{body.map((section, i) => {
const Component = sectionComponents[section.__component]
if (!Component) return null
return <Component key={i} {...section} />
})}
</>
)
}
Сроки
Создание набора компонентов для конструктора страниц (6–10 компонентов) — 1–2 дня.







