Какую CMS подключить к Next.js
Для Next.js в 2026 году есть одна CMS, которая живёт внутри самого приложения, это Payload, и несколько, которые подключаются снаружи по API: Strapi, Directus, Ghost, WordPress. Если проект начинается с нуля и фронт точно на Next.js, Payload снимает половину вопросов (два сервиса, два домена, CORS, сеть в Docker) просто тем, что их нет. Если CMS уже есть или её выбирают не под один фронт, берут Strapi или Directus и подключают по REST. Мы ведём в продакшене оба варианта, два сайта на Next.js со Strapi и портал с магазином на Next.js с Payload, и ниже сравнение по тому, что реально отличается: деплой, предпросмотр, кэш, ошибки.
Коротко
- Новый проект, всё на Next.js, есть логика (кабинет, заявки): Payload.
- CMS нужна нескольким фронтам или редакция хочет конструктор типов: Strapi.
- Есть SQL-база, нужна админка поверх неё: Directus.
- Контент уже в WordPress, переезд не по бюджету: WordPress по REST или WPGraphQL.
- Sanity, Contentful, Storyblok: из России не оплатить, в сравнении нет.
Два способа подключить CMS к Next.js
Внутри приложения. Так работает только Payload 3: он ставится как зависимость, добавляет группу роутов app/(payload) с админкой и API, и всё это собирается и деплоится вместе с сайтом. Серверные компоненты читают данные через Local API (payload.find()) без HTTP-запроса. Один контейнер, один домен, один набор переменных окружения.
Снаружи по API. Strapi, Directus, Ghost, WordPress работают как отдельный сервер. Next.js ходит в них по HTTP: на сборке, при ISR или на каждом запросе. Два сервиса, два домена (сайт и админка), CORS, токены доступа, сеть между контейнерами. Это нормальная схема, у нас так живут два корпоративных сайта, но она добавляет ровно ту работу, которой нет в первом варианте.
Таблица
| Критерий | Payload 3 | Strapi 5 | Directus 12 | WordPress headless |
|---|---|---|---|---|
| Где живёт | Внутри Next.js | Отдельный сервер Node.js | Отдельный сервер, Docker | Отдельный PHP-хостинг |
| Как читать данные | Local API без HTTP, плюс REST и GraphQL | REST, GraphQL плагином | REST, GraphQL в ядре, realtime | REST в ядре, WPGraphQL плагином |
| Схема контента | Код на TypeScript, типы генерируются | Content-Type Builder в режиме разработки, JSON в репозитории | Таблицы базы, правятся в интерфейсе на проде | ACF и плагины |
| Предпросмотр черновиков | Live Preview и Draft Mode в ядре | Preview в ядре, Live Preview в платном Growth | Preview через настройку URL коллекции | Руками через Draft Mode и REST с токеном |
| Обновление страниц | revalidateTag из хука afterChange в том же процессе | Вебхук Strapi на эндпоинт Next.js | Flow или вебхук на эндпоинт Next.js | Плагин вебхуков на эндпоинт Next.js |
| Картинки | Коллекция Media, S3 адаптером, next/image через remotePatterns | Плагин upload, S3 провайдером, next/image через remotePatterns и часто кастомный loader | Assets с трансформациями по URL | Медиатека WordPress |
| Деплой | Один контейнер Next.js плюс база | Контейнеры Strapi, Next.js, база, Nginx | Контейнеры Directus, Next.js, база, Redis по желанию | Хостинг PHP плюс хостинг Next.js |
| Авторизация пользователей сайта | Коллекция users с ролями, функции доступа | Плагин users-permissions | Роли и политики в ядре | Плагины |
| Лицензия и оплата | MIT, платного нет | MIT, Growth 45 $/мес по желанию | BSL 1.1, бесплатно до 5 млн $ выручки | GPL |
Где разница чувствуется
Деплой и сеть
На Payload у нас один контейнер Next.js и Postgres. На Strapi четыре: Strapi, Next.js, Postgres, Nginx, два домена и два набора переменных. Самая частая ошибка, которую мы ловили на проектах со Strapi: серверный код Next.js внутри Docker ходит в Strapi по внешнему https-домену, который изнутри сети недоступен, и падает с ECONNREFUSED или ENOTFOUND. Лечится двумя переменными: для серверных запросов адрес контейнера http://strapi:1337, для картинок в браузере публичный домен. Вторая ошибка: сборка Next.js падает с "Could not initialize the Strapi Client", если Strapi в момент сборки не поднят. Разбор с командами на strapi.tech. С Payload ни одной из этих ошибок не существует.
Кэш и обновление страниц
Next.js кэширует страницы, и после правки в CMS их нужно сбрасывать. С Payload это делается хуком afterChange в коллекции, который вызывает revalidateTag в том же процессе. Со Strapi и Directus нужен вебхук на эндпоинт сайта с секретом, и его надо не забыть настроить на каждом окружении. В Next.js 16 появились Cache Components (use cache, cacheTag, cacheLife, revalidateTag с профилем), но без флага cacheComponents классический ISR работает как раньше. Симптом, который знаком всем, кто подключал внешнюю CMS: "поправил в админке, а на сайте старое". Это кэш, а не CMS.
Предпросмотр
Редактору нужно видеть черновик до публикации. В Payload Live Preview в ядре: справа от полей открывается сайт и обновляется на лету. В Strapi 5 базовый Preview бесплатный, а Live Preview с правкой рядом с превью в платном плане Growth за 45 долларов. В Directus предпросмотр через настройку URL у коллекции. В WordPress headless предпросмотр собирается руками через Draft Mode Next.js и запрос черновика с токеном.
Картинки
С внешней CMS картинки лежат на другом домене, и next/image требует remotePatterns, а в Docker ещё и разные адреса для сервера и браузера. Классика: локально всё показывается, на проде нет. Разбор на strapi.tech. С Payload файлы отдаются тем же приложением, а для больших объёмов S3 через официальный адаптер.
Когда логики больше, чем контента
Пока это страницы и новости, все четыре варианта равны. Как только появляется кабинет, роли, заявки со статусами, обязательные файлы, Payload выигрывает: всё пишется хуками и функциями доступа в той же кодовой базе, что и сайт. Так устроен наш портал заявок: роли менеджера и сервисного центра, статусы, обязательные фото на уровне схемы, чат по заявке. На Strapi это тоже делается, но в двух репозиториях и с плагином users-permissions.
Когда не Payload
- Фронтов несколько на разных технологиях (Nuxt, Flutter, партнёрская витрина на PHP), и CMS должна быть нейтральной к ним: Strapi.
- Типов контента десятки, и структуру удобнее собирать в конструкторе: Strapi.
- Данные уже лежат в SQL-базе учётной системы и нужна админка поверх без переноса: Directus.
- Контент в WordPress, редакция к нему привыкла, бюджета на переезд нет: WordPress headless по REST.
- Нужна MySQL: Strapi или Directus, у Payload её нет.
Подробное сравнение двух главных кандидатов в Strapi или Payload, Directus отдельно в Strapi или Directus, все системы с ценами в сравнении headless CMS.
Сколько это стоит
Сам софт бесплатный во всех вариантах кроме платных планов Strapi. Сервер: VPS в России на 2 ядра и 4 ГБ около 1 000–1 300 рублей в месяц вмещает и Next.js, и CMS, и Postgres. Разработка по рыночным вилкам 2026 года: лендинг 200–400 тысяч, корпоративный сайт от 500 тысяч. Свою цену называем через день после просмотра задачи.
Напишите, что за проект на Next.js и что в нём должно быть: сколько типов контента, есть ли кабинет, кто ведёт контент. За день ответим, какую CMS подключать и во что это обойдётся. Разработку на Payload ведём на payload.agency, на Strapi на strapi.pro.
Частые вопросы
Какая CMS лучше всего подходит для Next.js?
Payload: он ставится внутрь приложения Next.js, админка открывается по /admin, серверные компоненты читают данные через Local API без HTTP, деплой один. Strapi и Directus тоже нормально работают с Next.js, но как отдельный сервис со своим доменом и контейнером.
Нужна ли вообще CMS для сайта на Next.js?
Если контент меняют раз в полгода и делает это разработчик, хватит Markdown-файлов в репозитории. CMS нужна, когда контент ведут не разработчики, страниц много или у данных есть структура: товары, проекты, регионы.
Как обновлять страницы Next.js после правки в CMS?
Через revalidateTag или revalidatePath из вебхука CMS: редактор нажал опубликовать, CMS дёрнула эндпоинт на сайте, Next.js пересобрал нужные страницы. В Next.js 16 с Cache Components это cacheTag и revalidateTag с профилем, без флага классический ISR работает как раньше.
Почему Next.js в Docker не видит Strapi?
Потому что серверный код Next.js ходит в Strapi по внешнему https-домену, который внутри сети Docker недоступен, и получает ECONNREFUSED или ENOTFOUND. Решение: две переменные, для серверных запросов адрес контейнера http://strapi:1337, для картинок в браузере публичный домен.
Можно ли использовать WordPress как CMS для Next.js?
Да, через REST API или плагин WPGraphQL. Это рабочий вариант, если контент уже в WordPress. Минусы: типы контента настраиваются через ACF, предпросмотр черновиков делается руками, остаётся PHP-хостинг и плагины.
Sanity или Payload для Next.js?
По интеграции с Next.js обе хороши: у Sanity официальный тулкит с live preview, у Payload всё внутри приложения. Разница в хостинге: Sanity только облако, которое из России не оплатить, Payload на любом сервере. Для российского проекта выбор фактически Payload.