Розробка CMS для контенту мобільного додатку
Мобільний додаток з хардкодним контентом — це постійні релізиради текстових правок. Змінити акційний баннер, оновити ціни, додати нову категорію — кожен раз ревью в App Store та Google Play, 24-72 години очікування. CMS (система управління контентом) виносить редактируємий контент за межі додатку: маркетолог змінює текст у браузері, користувачі бачать зміни через хвилину.
Що управляється через CMS
Не весь контент має смисл виносити у CMS. Правило просте: якщо це змінюється рідше раза на квартал та вимагає релізу — залишити у коді. Якщо змінюється часто та нетехнічними співробітниками — CMS.
Типично виносять:
- Баннери та промо-блоки на головному екрані
- Онбординг та сплеш-контент
- Тексти пуш-сповіщень та in-app повідомлень
- Каталог продуктів/послуг (якщо не з ERP)
- Статичні сторінки (FAQ, умови, контакти)
- Налаштування feature flags (показувати/ховати розділи)
- Локалізований контент (різні тексти для різних регіонів)
Вибір підходу
Headless CMS — відає контент через API, без фронтенду. Contentful, Strapi, Directus, Sanity. Мобільний додаток звертається до API та рендерить дані своїм UI.
Backend + Admin Panel — кастомна CMS на власному бекенді. Laravel Nova, Rails ActiveAdmin, кастомний React SPA. Повний контроль над структурою даних та логікою.
Firebase Remote Config — для feature flags та простих конфігураційних даних. Не для структурованого контенту з зображеннями.
Strapi та Directus — опенсорс, self-hosted, без плати за контент API. Contentful — платний hosted-сервіс, швидкий старт, є CDN.
API-контракт для мобільного клієнта
CMS повинна відавати дані у форматі, який мобільний клієнт може рендерити без додаткової трансформації. Типична помилка — CMS відає довільну структуру, мобільний розробник витрачає дні на парсинг.
Контракт для екрану головної сторінки:
{
"homeScreen": {
"version": 12,
"updatedAt": "2025-03-15T10:30:00Z",
"banners": [
{
"id": "banner-spring-sale",
"imageUrl": "https://cdn.example.com/banners/spring-sale-2x.webp",
"imageUrl2x": "https://cdn.example.com/banners/spring-sale-3x.webp",
"deepLink": "myapp://promo/spring-sale",
"title": "Весняна розпродажа",
"subtitle": "До -40% на все",
"backgroundColor": "#FF5733",
"textColor": "#FFFFFF",
"expiresAt": "2025-04-01T00:00:00Z",
"targetAudience": "all"
}
],
"featuredCategories": [...],
"announcements": [...]
}
}
Поле version — для клієнтського кеша. Якщо версія не змінилась з попереднього запиту, можна вернути 304 або використовувати кеш без повторної загрузки.
Клієнтська сторона: кеширування та оновлення
class CmsRepository(
private val api: CmsApi,
private val dao: CmsContentDao,
private val prefs: CmsPreferences
) {
fun observeHomeScreen(): Flow<HomeScreenContent> = flow {
// Одразу з кеша
val cached = dao.getHomeScreen()
if (cached != null) emit(cached.toContent())
// Перевіряємо оновлення
try {
val response = api.getHomeScreen(
ifNoneMatch = prefs.homeScreenEtag
)
if (response.code() == 304) return@flow // кеш актуален
val fresh = response.body()!!
dao.upsertHomeScreen(fresh.toEntity())
prefs.homeScreenEtag = response.headers()["ETag"]
emit(fresh)
} catch (e: IOException) {
// Сеть недоступна — кеш вже відданий
}
}
}
ETag-кеширування: сервер генерує хеш від контенту, клієнт присилає його у If-None-Match. Якщо контент не змінився — 304 без тіла. При 100K DAU та екрані, що завантажується 50 разів на день — це значна економія трафіку та нагрузки на сервер.
Локалізація контенту
CMS повинна підтримувати кілька локалей. Strapi v5 та Contentful мають вбудовану підтримку i18n — кожне поле може мати різні значення для різних мов.
API приймає Accept-Language: ru-RU у заголовку та відає контент на потрібній мові. Мобільний клієнт передає локаль користувача:
// iOS
var request = URLRequest(url: cmsEndpoint)
request.setValue(Locale.current.identifier, forHTTPHeaderField: "Accept-Language")
Feature Flags через CMS
CMS — зручне місце для feature flags. Не як A/B тест (для цього краще Firebase Remote Config або Unleash), а для управління видимістю розділів:
{
"featureFlags": {
"showCryptoPayments": true,
"enableDarkMode": true,
"referralProgramEnabled": false,
"maxCartItems": 50,
"minimumAppVersion": "2.4.0"
}
}
minimumAppVersion — CMS може заблокувати старі версії додатку м'яко: показати баннер «Оновіть додаток», не пускаючи до нових функцій. Без релізу.
Admin UI для нетехнічних редакторів
Кастомний admin panel повинен бути максимально простим для редакторів без технічного бекграунду: WYSIWYG для текстів, drag-and-drop для порядку баннерів, предпросмотр як у додатку, історія змін з можливістю відката.
Strapi з коробки дає хороший admin UI. Для кастомних сценаріїв — React з додаткальним дизайном.
Розробка headless CMS на Strapi або кастомному бекенді з мобільним API, кешуванням та admin UI: 3–6 тижнів. Вартість рассчитывается індивідуально.







