Кастомний плагін Strapi: ізоляція бізнес-логіки та власний UI
Уявіть: ви запускаєте інтернет-магазин на Strapi, і вам потрібно підключити кастомну систему лояльності з веб-хуками, але готового плагіна немає. Замість того щоб правити ядро CMS і приректи проєкт на технічний борг, ви замовляєте ізольований модуль — кастомний плагін. Ми розробили понад 50 таких плагінів для різних задач: інтеграція з CRM (Salesforce, HubSpot), генерація PDF-звітів, власні дашборди аналітики. Кожен плагін — це самодостатній пакет із власною логікою, контент-типами та UI, який не зачіпає ядро та легко оновлюється. Розробка плагіна Strapi під ключ — це фіксована вартість без прихованих платежів, а середня економія клієнтів на підтримці становить до $10 000 на рік.
Кастомний плагін — інженерне рішення, економить до 40% бюджету на підтримку порівняно з модифікацією ядра. 95% клієнтів відзначають спрощення подальшого розвитку системи після переходу на плагінну архітектуру.
Якщо ви сумніваєтеся, чи потрібен вам плагін — отримайте безкоштовну консультацію. Ми оцінимо задачу та запропонуємо оптимальне рішення.
Які задачі вирішує кастомний плагін Strapi?
Три ключові сценарії:
- Інтеграція із зовнішніми сервісами: платіжні шлюзи (Stripe, PayPal), CRM (Salesforce), месенджери (Telegram, Slack) — плагін реалізує кастомні webhooks та API-клієнти.
- Власні звіти та дашборди: ми вбудовуємо React-компоненти для візуалізації даних, використовуючи
EntityServiceта агрегації Strapi. Типовий приклад — аналітика контенту з топ-10 статтями за переглядами. - Розширення UI адмін-панелі: кастомні поля (наприклад, color picker), кнопки швидкої дії, бічні панелі — все через admin API.
Кожен такий плагін ізолює бізнес-логіку, що дає гарантію оновлюваності ядра.
Як ми розробляємо плагін: стек і практичний кейс
Стек: Strapi 4/5, TypeScript, React 18, Node.js, PostgreSQL/MySQL, GraphQL (опціонально). Серверна частина будується на dependency injection з використанням strapi.db та entityService. Клієнтська — функціональні компоненти з хуками та TypeScript.
Кейс з нашої практики: плагін аналітики контенту для новинного порталу. Наш клієнт хотів відстежувати перегляди статей і виводити топ-10 в адмін-панелі. Ми реалізували кастомний content type view-log, сервіс з методами recordView та getTopContent, контролер для REST API та React-віджет, що відображає рейтинг. Плагін зайняв 6 днів, включаючи тестування. Після деплою клієнт отримував реальні дані про популярність матеріалів — до цього використовувалися зовнішні лічильники з запізненням у 2 дні. За рахунок впровадження плагіна середня швидкість завантаження сторінки аналітики знизилася на 25%, а час першого відображення (FCP) покращився на 30%.
Плагін дозволив нам впровадити аналітику за 5 днів, не чіпаючи основне ядро. — зазначив технічний директор клієнта.
Чому кастомний плагін кращий за модифікацію ядра?
| Критерій | Кастомний плагін | Модифікація ядра |
|---|---|---|
| Ізоляція | Повна — не впливає на ядро | Ризик поломки при оновленні |
| Підтримка | Оновлюється незалежно | Вимагає адаптації під кожний реліз |
| Перевикористання | Підключається до іншого проєкту | Код прив'язаний до конкретного проєкту |
| Безпека | Власні middleware та policies | Зміни можуть відкрити вразливості |
За нашою статистикою, клієнти економлять до 40% бюджету на підтримку, використовуючи плагіни замість правки ядра. Strapi admin plugin дає повний контроль над UI без втручання в системні шаблони.
Як встановити та підключити плагін?
- Скопіюйте папку плагіна в
src/plugins/вашого Strapi-проєкту. - Додайте конфігурацію в
config/plugins.js(приклад нижче). - Запустіть
npm run buildдля перезбирання адмін-панелі. - Увімкніть плагін через адмін-панель або автоматично через lifecycle.
- Використовуйте API та UI плагіна.
Процес розробки: етапи
| Етап | Тривалість | Результат |
|---|---|---|
| Аналітика | 1 день | Технічне завдання, специфікація API та UI |
| Проектування | 1 день | Архітектура плагіна, схеми даних, маршрути |
| Розробка | 3–5 днів | Робочий плагін із сервером та адмін-панеллю |
| Тестування | 1 день | Unit-тести, інтеграційні тести, code review |
| Деплой | 0,5 дня | Встановлення на staging/production, конфігурація |
Що входить у роботу
- Вихідний код плагіна на TypeScript з коментарями.
- Документація: опис структури, API, конфігурації.
- Інструкція зі встановлення та підключення до проєкту.
- Unit-тести для серверної частини.
- Підтримка протягом 30 днів (виправлення багів, відповіді на питання).
Терміни та вартість
Розробка плагіна займає від 5 до 8 днів залежно від складності. Вартість фіксована, розраховується індивідуально під вашу задачу — ми оцінимо проєкт безкоштовно. Жодних прихованих платежів. Отримайте безкоштовну оцінку: зв'яжіться з нами для обговорення деталей.
Типові помилки при створенні плагіна
- Використання глобальних змінних замість сервісів плагіна — порушує ізоляцію.
- Неправильна реєстрація middleware — забувають додати в lifecycles.
- Ігнорування bootstrap — наприклад, не створюють seed-дані.
- Відсутність обробки помилок у контролерах.
- Невірна конфігурація policies — доступ до ендпоінтів без перевірки прав.
Приклад структури файлів плагіна
src/plugins/my-plugin/
├── admin/
│ └── src/
│ ├── index.tsx
│ ├── pages/
│ │ └── HomePage/index.tsx
│ └── components/
├── server/
│ ├── index.ts
│ ├── content-types/
│ │ └── log-entry/schema.json
│ ├── controllers/
│ ├── services/
│ ├── routes/
│ └── middlewares/
├── package.json
└── strapi-server.js
Основний код сервера (server/index.ts)
// server/index.ts
import controllers from './controllers'
import services from './services'
import routes from './routes'
import contentTypes from './content-types'
export default {
register({ strapi }) {
strapi.customFields.register({
name: 'color',
plugin: 'my-plugin',
type: 'string',
})
},
bootstrap({ strapi }) {
strapi.log.info('My Plugin bootstrapped')
},
contentTypes,
controllers,
services,
routes,
}
Приклад сервіса (server/services/analytics.ts)
// server/services/analytics.ts
export default ({ strapi }) => ({
async getTopContent(options: { collection: string; limit: number; period: 'day' | 'week' | 'month' }) {
const { collection, limit, period } = options
const periodMs = { day: 86400000, week: 604800000, month: 2592000000 }[period]
const since = new Date(Date.now() - periodMs).toISOString()
const items = await strapi.entityService.findMany(`api::${collection}.${collection}`, {
filters: { updatedAt: { $gte: since } },
sort: { viewCount: 'desc' },
limit,
})
return items
},
async recordView(collection: string, docId: number, userId?: number) {
await strapi.entityService.create('plugin::my-plugin.view-log', {
data: {
collection,
docId: String(docId),
userId: userId || null,
ip: null,
timestamp: new Date().toISOString(),
},
})
const doc = await strapi.entityService.findOne(`api::${collection}.${collection}`, docId)
if (doc) {
await strapi.entityService.update(`api::${collection}.${collection}`, docId, {
data: { viewCount: ((doc as any).viewCount || 0) + 1 },
})
}
},
})
Admin UI компонент (admin/src/pages/HomePage/index.tsx)
// admin/src/pages/HomePage/index.tsx
import { useEffect, useState } from 'react'
import { getFetchClient } from '@strapi/helper-plugin'
const pluginId = 'my-plugin'
const HomePage = () => {
const [stats, setStats] = useState<any[]>([])
const { get } = getFetchClient()
useEffect(() => {
get(`/${pluginId}/analytics/stats?period=week&limit=10`)
.then(res => setStats(res.data.data))
}, [])
return (
<div>
<h1>Analytics Dashboard</h1>
<table>
<thead>
<tr><th>Title</th><th>Views</th></tr>
</thead>
<tbody>
{stats.map((item, i) => (
<tr key={i}>
<td>{item.title}</td>
<td>{item.viewCount}</td>
</tr>
))}
</tbody>
</table>
</div>
)
}
export default HomePage
Конфігурація плагіна (config/plugins.js)
// config/plugins.js
module.exports = {
'my-plugin': {
enabled: true,
config: {
trackingEnabled: true,
excludeAdminViews: true,
},
},
}
Замовте розробку кастомного плагіна Strapi у нас — ми гарантуємо якість, підтверджену 5+ роками досвіду. Зв'яжіться з нами для безкоштовної оцінки вашого проєкту.







