Рано или поздно блог нужен любой SaaS-компании: для анонсов продукта, руководств и длинного хвоста поискового трафика, который накапливается годами. Большинство команд разработки ошибаются, когда видят в задаче «добавить блог» либо установку WordPress на выходных, либо внутренний проект по CMS на квартал. Есть третий путь, и он даёт рабочий блог на вашем домене за полдня.
Где будет жить блог: поддомен или подкаталог
Прежде чем писать код, определитесь с адресом. Вариантов три:
blog.yourapp.com— поддомен, который обычно указывает на отдельную стороннюю платформу.yourapp.com/blog— подкаталог основного сайта, который отрисовывает ваш собственный фронтенд.Чужой домен — публикация на Medium или похожей площадке.
Для SEO подкаталог сильнее всего: каждая статья наращивает авторитет домена, на котором живёт продукт, внутренние ссылки естественно связывают маркетинговые страницы и посты, а аналитика остаётся в одном ресурсе. Поддомен — рабочий вариант. На чужом домене авторитет копится целиком у кого-то другого.
У подкаталога есть архитектурное следствие: посты должно отрисовывать ваше собственное приложение. Это исключает монолитные платформы, которые непременно отдают страницы сами, и ведёт к схеме API-first: контент пишут в панели управления, получают в виде JSON и отрисовывают вашим фронтендом.
Архитектура из трёх слоёв
Блогу SaaS нужно ровно три слоя, и только один из них — ваш код:
Редактирование — панель управления, где пишут посты: визуальный редактор, теги, категории, черновики, SEO-метаданные (заголовок, описание, изображение для Open Graph) и отложенная публикация.
Доставка — API, который отдаёт опубликованные посты в JSON, с пагинацией, фильтром по тегам и поиском.
Отрисовка — два маршрута в вашем приложении: страница списка и страница поста.
Именно на слоях 1 и 2 внутренние проекты блогов и умирают: один редактор — это недели работы, а следом идут загрузка изображений, черновики, права доступа и слаги. Контент-бэкенд даёт оба слоя как сервис, и весь ваш проект сводится к третьему.
Отрисовка: два маршрута и запрос
С типизированным SDK слой отрисовки получается небольшим. Страница списка запрашивает страницу постов:
const { data: posts } = await kookee.blog.list({ page: 1, limit: 10 });
Страница поста запрашивает пост по слагу:
const post = await kookee.blog.getBySlug(params.slug);
Отрисуйте текст своими компонентами в вашей дизайн-системе. В React работы ещё меньше: хуки вроде useBlogPosts и useBlogPost берут на себя состояния загрузки и пагинацию, а компонент контента сам выводит HTML поста. А можно вовсе не писать разметку: серверные компоненты отрисовывают список постов, фильтр по тегам, пагинацию и страницу поста из полученных вами данных. Подробнее — в статье Блог на React-компонентах.
Качество держат два правила:
Отрисовывайте на сервере. SSR или статическая генерация отдают краулерам и читателям готовый HTML. Отрисовка только на клиенте тоже работает, но тогда вы теряете SEO, ради которого выбрали подкаталог.
Отдавайте настоящий 404. Если слаг не найден, отвечайте статусом 404, а не оформленной страницей «не найдено» со статусом 200. Мягкие 404 засоряют индекс.
Чек-лист метаданных
Каждая страница поста должна выводить из данных, которые CMS уже хранит:
<title>и meta description из SEO-полей поста.Канонический URL, который указывает на собственный адрес поста.
Теги Open Graph и Twitter Card, включая изображение поста.
article:published_timeиarticle:modified_time.Структурированные данные JSON-LD
Article.
Всё это берётся из одного ответа API, поэтому помещается в одну вспомогательную функцию. Добавьте RSS-ленту и запись в sitemap для каждого поста: и то и другое легко сгенерировать из того же эндпоинта list, который уже вызывает страница блога.
Теги, поиск и функции, которые достаются даром
Когда посты — структурированные данные, функции, которые в самописной системе были бы отдельными проектами, становятся параметрами запроса:
Страницы тегов:
kookee.blog.list({ tags: ['engineering'] })на маршруте/blog/tags/:tag.Поиск:
kookee.blog.list({ search: query })для строки поиска.Комментарии и реакции: их отдаёт тот же API, если вы хотите, чтобы читатели откликались на посты.
Переводы: запрашивайте другие языковые версии поста, когда выйдете на другие рынки.
Ничто из этого не требует менять схему или писать миграции на вашей стороне: в бэкенде всё это уже есть.
Во что это обойдётся
Честный подсчёт для пути API-first:
Ваш код: два маршрута, функция для метаданных, лента. День работы в большинстве фреймворков, меньше, если начать с готовых шаблонов страниц.
Регулярно: подписка на контент-платформу. У бесплатных тарифов лимит по объёму использования (в Kookee — 100 000 запросов к API в месяц), и обычный блог долго живёт на бесплатном тарифе.
Что не придётся делать: писать и поддерживать редактор, хранилище медиафайлов, процесс публикации и второе развёрнутое приложение.
Сравните с самостоятельным хостингом: первая версия занимает недели, а потом вы навсегда отвечаете за патчи безопасности и обновления зависимостей системы, которая даже не ваш продукт.
Порядок работ
Создайте проект в контент-бэкенде и напишите один тестовый пост.
Добавьте маршруты
/blogи/blog/:slug, которые получают пост и отрисовывают его на сервере.Подключите функцию метаданных: title, description, canonical, теги OG, JSON-LD.
Добавьте фильтр по тегам и RSS-ленту.
Отправьте команду в панель управления и вычеркните «сделать блог» из бэклога разработки.
Сам блог сделать несложно. Сложнее направить силы разработки в продукт и при этом дать маркетингу быстрый блог в фирменном стиле на своём домене. Именно это и даёт разделение на контент-бэкенд и тонкий слой отрисовки.