Headless WordPress — это схема, где WordPress остается только хранилищем контента и панелью для редакторов, а страницы посетителям показывает отдельное фронтенд-приложение на React, Vue или Next.js. WordPress отдает данные через API, фронтенд их запрашивает и рисует по своим шаблонам. Разберем, когда такая схема оправдана и как собрать связку без потери скорости.
Когда нужен headless, а когда — обычная тема
Headless-схема оправдана, если у проекта уже есть команда фронтенд-разработчиков, нужна единая кодовая база для сайта и мобильного приложения, либо контент нужно показывать в нескольких каналах сразу — на сайте, в приложении, в виджете партнера. Если задача — обычный сайт-визитка или блог, классическая тема WordPress с кэшированием обойдется дешевле и надежнее.
Минус headless-подхода — двойная инфраструктура: нужно поддерживать и WordPress, и отдельный фронтенд-сервер или статический хостинг для сборки.
Как WordPress отдает данные фронтенду
Основной канал — встроенный REST API WordPress, который отдает записи и страницы по адресам вида /wp-json/wp/v2/posts. Для сложных выборок с вложенными связями (запись, автор, категории и медиа одним запросом) многие проекты ставят плагин WPGraphQL — он добавляет эндпоинт /graphql с гибкими запросами вместо десятка отдельных REST-вызовов.
curl -s https://site.example/wp-json/wp/v2/posts?per_page=5&_embed=1
Параметр _embed=1 подгружает автора, категории и обложку записи в одном ответе — без него фронтенду пришлось бы делать отдельный запрос на каждую связанную сущность.
Пример запроса данных во фронтенд-приложении
На стороне Next.js запрос к REST API выглядит как обычный fetch на этапе сборки страницы.
export async function getStaticProps() {
const res = await fetch('https://site.example/wp-json/wp/v2/posts?_embed=1');
const posts = await res.json();
return { props: { posts }, revalidate: 60 };
}
Опция revalidate: 60 включает инкрементальную регенерацию: страница пересобирается не чаще раза в 60 секунд, а не при каждом заходе посетителя.
Как обновлять фронтенд после публикации записи
Ждать плановую пересборку не всегда удобно — редактор ждет, что материал появится сразу после нажатия «Опубликовать». Решение — вебхук: хук WordPress publish_post дергает URL пересборки на стороне фронтенда.
<?php
add_action('publish_post', function ($post_id) {
wp_remote_post('https://frontend.example/api/revalidate', array(
'body' => array('secret' => 'REPLACE_WITH_TOKEN', 'post_id' => $post_id),
'timeout' => 5,
));
});
Секретный токен в теле запроса нужен, чтобы посторонние не могли вызывать пересборку по своему желанию и создавать лишнюю нагрузку.
Headless и классический WordPress: сравнение
| Параметр | Headless | Классическая тема |
|---|---|---|
| Скорость фронтенда | высокая при статической сборке | зависит от кэша и хостинга |
| Порог входа | нужен фронтенд-разработчик | достаточно верстальщика |
| SEO из коробки | требует настройки meta-тегов вручную | решают Yoast SEO и подобные |
| Предпросмотр черновика | нужен отдельный режим preview | работает сразу |
Частые проблемы связки
CORS-ошибки в консоли браузера означают, что REST API не разрешает запросы с домена фронтенда — добавьте заголовок Access-Control-Allow-Origin через фильтр rest_pre_serve_request. Долгие ответы API на сайте с большим числом записей обычно лечит объектный кэш — подробности в статье про Redis-кэш для WordPress. Автоматизировать проверку и очистку кэша при деплое удобно скриптом на базе WP-CLI.
Чек-лист перед запуском headless-проекта
- Определена связка API: чистый REST API или дополнительно WPGraphQL для сложных выборок.
- Настроен вебхук пересборки фронтенда при публикации и обновлении записей.
- Добавлен режим предпросмотра черновиков для редакторов до публикации.
- Настроены заголовки CORS для домена фронтенда.
- Объектный кэш на стороне WordPress снижает нагрузку от частых запросов API.