Інтеграція CMS Strapi для управління контентом
Strapi — headless CMS з відкритим вихідним кодом на Node.js. Надає адміністративну панель для управління контентом та автоматично генерує REST та GraphQL API за створеними типами контенту. Розгортується на власному сервері — дані залишаються під контролем.
Архітектура
Strapi складається з двох частин: Admin Panel — React-додаток для управління контентом, схемами та настройками; Backend — Node.js/Koa сервер з автогенерованими маршрутами API.
Headless-робочий процес:
Strapi Admin → створює контент
Strapi API → обслуговує контент клієнтам
Frontend → Next.js / Nuxt / мобільний додаток
Установка
npx create-strapi-app@latest my-cms --quickstart
# або з базою даних
npx create-strapi-app@latest my-cms \
--dbclient=postgres \
--dbhost=127.0.0.1 \
--dbport=5432 \
--dbname=strapi \
--dbusername=strapi \
--dbpassword=secret
Підтримані бази даних: SQLite (розробка), PostgreSQL, MySQL/MariaDB.
Content Types
Створюємо через Content-Type Builder у admin (drag-and-drop) або вручну:
src/api/article/content-types/article/schema.json
{
"kind": "collectionType",
"collectionName": "articles",
"info": {
"singularName": "article",
"pluralName": "articles",
"displayName": "Article"
},
"attributes": {
"title": { "type": "string", "required": true },
"slug": { "type": "uid", "targetField": "title" },
"content": { "type": "richtext" },
"cover": { "type": "media", "allowedTypes": ["images"] },
"author": { "type": "relation", "relation": "manyToOne", "target": "plugin::users-permissions.user" },
"publishedAt": { "type": "datetime" }
}
}
Зміни схеми автоматично створюють міграції при наступному запуску.
API-запити
# Отримати всі статті
GET /api/articles
# З populate для зв'язків
GET /api/articles?populate=cover,author
# Фільтрування
GET /api/articles?filters[title][$containsi]=strapi&filters[publishedAt][$notNull]=true
# Сортування та пагінація
GET /api/articles?sort=publishedAt:desc&pagination[page]=1&pagination[pageSize]=10
Відповідь:
{
"data": [
{
"id": 1,
"attributes": {
"title": "Getting started with Strapi",
"slug": "getting-started",
"content": "<p>...</p>",
"publishedAt": "2025-03-01T10:00:00.000Z",
"cover": { "data": { "attributes": { "url": "/uploads/cover.jpg" } } }
}
}
],
"meta": { "pagination": { "page": 1, "pageSize": 10, "total": 42 } }
}
Кастомні маршрути та контролери
// src/api/article/routes/custom-article.js
module.exports = {
routes: [
{
method: 'GET',
path: '/articles/featured',
handler: 'article.featured',
},
],
};
// src/api/article/controllers/article.js
module.exports = {
async featured(ctx) {
const articles = await strapi.entityService.findMany('api::article.article', {
filters: { featured: true, publishedAt: { $notNull: true } },
sort: { publishedAt: 'desc' },
limit: 6,
populate: ['cover'],
});
return { data: articles };
},
};
Lifecycle Hooks
// src/api/article/content-types/article/lifecycles.js
module.exports = {
async beforeCreate(event) {
const { data } = event.params;
if (!data.slug) {
data.slug = slugify(data.title);
}
},
async afterCreate(event) {
const { result } = event;
// сповітити канал, очистити кеш, індексувати в Algolia
await notifyChannel('new-article', result.id);
},
};
Інтернаціоналізація
Вбудований плагін i18n:
# Включити у admin: Settings → Internationalization → Add locale
У схемі увімкнути pluginOptions: { i18n: { localized: true } } для потрібних полів. API: GET /api/articles?locale=uk.
Деплой на production
# docker-compose.yml
services:
strapi:
image: node:20-alpine
command: yarn start
environment:
NODE_ENV: production
DATABASE_URL: postgres://user:pass@db:5432/strapi
JWT_SECRET: ${JWT_SECRET}
db:
image: postgres:16
Для production виносимо медіафайли в S3 через @strapi/provider-upload-aws-s3.
Терміни
Установка, настройка типів контенту, REST API, права доступу, деплой — 3–5 днів. З кастомними плагінами, i18n, вебхуками, моніторингом — 1–2 тижні.







