Кастомний плагін 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+ роками досвіду. Зв'яжіться з нами для безкоштовної оцінки вашого проєкту.







