Headless CMS и SEO: что действительно важно

headless-cms

«Если контент живёт в API, Google его вообще увидит?» — этот вопрос задаёт каждая команда перед переходом на headless. Обычно его поднимает тот, кто в 2019 году видел, как клиентское React-приложение отдаёт поисковому роботу пустой <div>. Опасение устарело, но за ним стоит настоящий вопрос: с headless ответственность за SEO переходит от CMS к вам. Этот пост — карта того, за что вы теперь отвечаете.

Короткий ответ

Поисковики ранжируют HTML, который отдают адреса на вашем домене. Им неизвестно и неважно, из чего этот HTML собран: из базы данных, API или Markdown-файлов. Headless с серверным рендерингом выдаёт роботу ровно то же, что и традиционная CMS, а часто и лучше, потому что каждый байт страницы под вашим контролем.

Подвох в условии: с серверным рендерингом. Выберите правильную модель рендеринга, и остальное — обычное техническое SEO.

Главное решение — рендеринг

Превратить контент из API в страницы можно тремя способами:

  • Клиентский рендеринг (CSR): браузер загружает JSON и собирает страницу на JavaScript. Google умеет выполнять JavaScript, но рендерит такие страницы с задержкой, а другие роботы, превью ссылок и парсеры соцсетей ведут себя по-разному. Для контента, который должен ранжироваться, CSR — рискованный выбор.

  • Серверный рендеринг (SSR): ваш сервер на каждый запрос получает данные из API контента и возвращает готовый HTML. Роботы видят страницу всегда, правки появляются сразу, а цена — один запрос к API на каждый запрос страницы (кэшируйте, как считаете нужным).

  • Статическая генерация (SSG): страницы собираются заранее и отдаются как файлы. Это самая быстрая доставка, но при изменении контента нужна пересборка или ревалидация.

Любой современный фреймворк — Next.js, Astro, Nuxt, SvelteKit, TanStack Start — по умолчанию рассчитан на SSR или SSG поверх API контента: запрос к API делается в лоадере или при сборке. Если запомнить из этого поста одно правило, то такое: публичные страницы с контентом рендерятся на сервере.

Преимущество своего домена, о котором молчат

Переход на headless часто улучшает SEO по структурной причине: контент оказывается на вашем основном домене. Хостинговые платформы для блогов и документации живут на поддоменах или на своих доменах, и авторитет, который зарабатывают ваши статьи, копится там. С headless /blog, /help и /changelog — подкаталоги домена, на котором живёт ваш продукт, и каждая обратная ссылка на статью усиливает все остальные ваши страницы. Обычно один этот фактор весит больше, чем все детали с метатегами ниже.

Чек-лист, который теперь на вас

Традиционная CMS делает часть этой работы незаметно. Headless передаёт её вам. Настроить всё нужно один раз, во вспомогательной функции, потому что всё выводится из одних и тех же ответов API.

Метаданные каждой страницы

Title, meta description, теги Open Graph и Twitter, даты статьи. Заполняйте их как поля в CMS рядом с контентом и выводите в head документа из того же запроса, которым рендерится страница. Если бэкенд контента хранит SEO-поля у каждой записи (заголовок, описание, картинку), задача сводится к сопоставлению полей, а не превращается в отдельный проект.

Канонические URL

Каждая страница объявляет свой канонический URL, вычисленный из slug записи. Никогда не копируйте его из адреса запроса: иначе каноническими станут варианты с ?utm_source= и случайные адреса с другим регистром букв. Одна функция, которая переводит запись в путь и которой пользуются страницы, карта сайта и фиды, гарантирует, что они никогда не разойдутся.

Настоящие коды ответа

Неизвестный slug должен возвращать HTTP 404, а не оформленную страницу ошибки со статусом 200. Мягкие 404 тратят краулинговый бюджет и засоряют индекс. И если серверный маршрут не может достучаться до API контента, отвечайте 5xx с Cache-Control: no-store, а не кэшируйте пустой ответ 200 на CDN.

Карта сайта и фиды

Генерируйте sitemap.xml из тех же эндпоинтов списков, что и страницы со списками, с настоящим lastmod из дат записей. Добавьте RSS для блога и журнала изменений: фиды почти ничего не стоят, а пользуются ими и читатели, и роботы.

Структурированные данные

Выводите JSON-LD (Article для постов, FAQPage там, где подходит, Organization на главной) из данных записи. Одна тонкость при вставке JSON-LD из серверного кода: экранируйте каждый < в сериализованном JSON как \\u003c, чтобы случайный </script> в заголовке не вырвался за пределы тега script.

Noindex для того, что не должно ранжироваться

Страницам результатов поиска, маршрутам предпросмотра и постраничным комбинациям тегов часто нужен noindex. Если платформа кроме API даёт ещё и готовый портал на своём домене, проверьте, как она обходится с индексацией. Страницы портала Kookee намеренно закрыты от индексации: в поиске участвует только версия того же контента на вашем домене, и вопроса о дублях не возникает.

Свежесть контента и кэш

С SSR опубликованная правка видна со следующего запроса. С SSG решите для каждого типа контента, насколько он может отставать: блог можно пересобирать лениво, а журналу изменений или странице, где важен актуальный статус, нужна ревалидация в пределах минут. В любом случае кэшируйте на CDN осознанно: ключ кэша — URL, разумные TTL и сброс кэша при публикации, если платформа поддерживает вебхуки или вы запускаете пересборку при публикации.

Многоязычный контент

Если у вас несколько языков, headless и тут даёт чистый вариант: получайте переводы записи из API, отдавайте каждый язык по своему адресу и выводите альтернативные ссылки hreflang из списка переводов. От машинного перевода на скорую руку он не спасёт: публикуйте только те языки, которые поддерживаете.

Проверка, которую можно сделать сегодня

Возьмите самую ценную страницу и проверьте её с отключённым JavaScript. Есть ли весь текст в исходном HTML? Соответствуют ли title, description и canonical этой странице? Возвращает ли бессмысленный slug 404? Откройте sitemap.xml: есть ли там страница с правдоподобным lastmod? Пятнадцать минут, и проверено 90% того, что обычно ломается.

Headless не вредит SEO. Вредят JavaScript, который никто не отрендерил, и неправильные коды ответа, а поддомены вендора незаметно отнимают часть результата. Выбирайте серверный рендеринг, выводите каждый сигнал из данных записи, которые вы и так получаете, и держите авторитет на единственном домене, который должен его зарабатывать, — на вашем.