Headless WordPress: інтеграція WP REST API з React і Next.js

Headless WordPress: інтеграція WP REST API з React і Next.js

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Headless WordPress: інтеграція WP REST API з React і Next.js
Середній
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Headless WordPress: інтеграція WP REST API з React і Next.js

Типова проблема: бізнесу потрібен керований контент у WordPress, але готові теми не забезпечують потрібну продуктивність або кастомізацію. Рішення — headless CMS, де WordPress залишається бекендом, а фронтенд будується на React, Vue, Next.js або Svelte. Це позбавляє від монолітних тем, прискорює завантаження сторінок (LCP знижується на 30–50%) і спрощує підтримку. За 5+ років ми реалізували понад 50 таких проєктів — від інтернет-магазинів до корпоративних порталів. Бюджет інтеграції порівнянний з вартістю одного місяця роботи фронтенд-розробника, але окупається за рахунок зниження витрат на хостинг і прискорення виведення нових сторінок.

Які завдання вирішує headless WordPress?

  • Відділення контенту від представлення: редактори працюють у звичній адмінці WordPress, а розробники використовують сучасний стек (React, Next.js, Vue). Більше не потрібно підганяти шаблони під дизайн — API віддає чисті дані.
  • Підвищення продуктивності: статичні сторінки (SSG) та ISR скорочують TTFB до 200 мс, а LCP — до 2 с. Економія на серверних ресурсах сягає 40% за рахунок кешування.
  • Єдине API для всіх клієнтів: один WordPress може обслуговувати SPA, мобільний додаток і телеграм-бота — через REST або GraphQL.

Базова інтеграція: отримання даних

WordPress REST API за замовчуванням доступний за /wp-json/wp/v2/. Отримання останніх постів:

// lib/wordpress.ts const WP_API_URL = process.env.NEXT_PUBLIC_WP_URL + '/wp-json/wp/v2'; export interface WPPost { id: number; slug: string; title: { rendered: string }; content: { rendered: string }; excerpt: { rendered: string }; date: string; featured_media: number; _embedded?: { 'wp:featuredmedia'?: [{ source_url: string; alt_text: string }]; 'wp:term'?: Array<Array<{ id: number; name: string; slug: string }>>; }; } export async function getPosts(params: { perPage?: number; page?: number; category?: number; search?: string; } = {}): Promise<{ posts: WPPost[]; total: number; totalPages: number }> { const qs = new URLSearchParams({ per_page: String(params.perPage ?? 12), page: String(params.page ?? 1), _embed: 'wp:featuredmedia,wp:term', ...(params.category && { categories: String(params.category) }), ...(params.search && { search: params.search }), }); const res = await fetch(`${WP_API_URL}/posts?${qs}`, { next: { revalidate: 60 }, // ISR в Next.js 13+ }); if (!res.ok) throw new Error(`WP API error: ${res.status}`); return { posts: await res.json(), total: Number(res.headers.get('X-WP-Total')), totalPages: Number(res.headers.get('X-WP-TotalPages')), }; } export async function getPostBySlug(slug: string): Promise<WPPost | null> { const res = await fetch(`${WP_API_URL}/posts?slug=${slug}&_embed=wp:featuredmedia,wp:term`); const posts = await res.json(); return posts.length ? posts[0] : null; } 

Next.js App Router: динамічні маршрути

// app/blog/[slug]/page.tsx import { getPostBySlug, getPosts } from '@/lib/wordpress'; import { notFound } from 'next/navigation'; export async function generateStaticParams() { const { posts } = await getPosts({ perPage: 100 }); return posts.map(post => ({ slug: post.slug })); } export async function generateMetadata({ params }: { params: { slug: string } }) { const post = await getPostBySlug(params.slug); if (!post) return {}; return { title: post.title.rendered, description: post.excerpt.rendered.replace(/<[^>]+>/g, '').slice(0, 160), }; } export default async function PostPage({ params }: { params: { slug: string } }) { const post = await getPostBySlug(params.slug); if (!post) notFound(); const media = post._embedded?.['wp:featuredmedia']?.[0]; return ( <article className="post-single"> {media && ( <img src={media.source_url} alt={media.alt_text} className="post-single__cover" /> )} <h1 dangerouslySetInnerHTML={{ __html: post.title.rendered }} /> <div className="post-content" dangerouslySetInnerHTML={{ __html: post.content.rendered }} /> </article> ); } 

dangerouslySetInnerHTML тут допустимий — контент від довіреного сервера, але якщо джерело під вашим контролем, додайте DOMPurify для безпеки.

Кастомний хук для React SPA

// hooks/usePosts.ts import useSWR from 'swr'; const fetcher = (url: string) => fetch(url).then(r => r.json()); export function usePosts(category?: string, page = 1) { const params = new URLSearchParams({ per_page: '12', page: String(page), _embed: '1' }); if (category) params.set('categories', category); const { data, error, isLoading } = useSWR<WPPost[]>( `/wp-json/wp/v2/posts?${params}`, fetcher, { revalidateOnFocus: false } ); return { posts: data ?? [], isLoading, error }; } 

Використовуйте цей хук з пагінацією та скелетонами. Приклад компонента — в документації SWR.

Як налаштувати on-demand ISR для миттєвого оновлення контенту?

Next.js підтримує перебудову сторінок за тригером. Коли пост публікується в WordPress, PHP-код надсилає POST-запит на ендпоінт /api/revalidate у Next.js:

// WordPress: save_post hook і CORS filter add_action('save_post', function (int $post_id, WP_Post $post): void { if ($post->post_status !== 'publish') return; $next_url = get_option('nextjs_revalidate_url'); $secret = get_option('nextjs_revalidate_secret'); if (!$next_url || !$secret) return; wp_remote_post("{$next_url}/api/revalidate", [ 'body' => json_encode([ 'secret' => $secret, 'path' => '/' . $post->post_type . '/' . $post->post_name, ]), 'headers' => ['Content-Type' => 'application/json'], 'blocking'=> false, ]); }, 10, 2); add_filter('rest_pre_serve_request', function ($value) { $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; $allowed = ['https://mysite.com', 'https://www.mysite.com', 'http://localhost:3000']; if (in_array($origin, $allowed)) { header('Access-Control-Allow-Origin: ' . $origin); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Authorization, Content-Type'); } return $value; }); 

А на стороні Next.js обробляємо:

// Next.js: app/api/revalidate/route.ts import { revalidatePath } from 'next/cache'; export async function POST(req: Request) { const { secret, path } = await req.json(); if (secret !== process.env.REVALIDATE_SECRET) { return Response.json({ error: 'Invalid secret' }, { status: 401 }); } revalidatePath(path); return Response.json({ revalidated: true, path }); } 

Цей пайплайн забезпечує оновлення сторінок за секунди без повної перебудови сайту. Економія трафіку — до 40% порівняно з повною регенерацією.

Продуктивність: що кешувати

Дані Стратегія
Список постів ISR, revalidate: 60s
Одиночний пост ISR + on-demand revalidate при save_post
Меню навігації Static (revalidate: false)
Пошукові результати SSR (без кешу, параметри змінюються)
ACF-поля налаштувань сайту Static або revalidate: 3600s

Порівняння REST і GraphQL

Критерій REST GraphQL
Гнучкість запитів Фіксовані поля Вибір лише потрібних даних
Кількість запитів Часто декілька Один
Складність налаштування Мінімальна Потрібен плагін та схема
Продуктивність Висока для простих сторінок Краще для складних вкладень

Як проходить інтеграція headless WordPress

  1. Аудит — розбираємо поточну архітектуру WordPress, плагіни, обсяг контенту, навантаження.
  2. Проектування — визначаємо необхідні endpoint’и, поля, стратегію кешування (ISR, SSG, SSR).
  3. Налаштування API — розширюємо REST або встановлюємо WPGraphQL, додаємо custom fields (ACF).
  4. Розробка фронтенду — створюємо типізований клієнт (TypeScript), компоненти, маршрутизацію.
  5. Інтеграція — підключаємо CORS, on-demand revalidation, деплоїмо WordPress і фронтенд.
  6. Тестування — перевіряємо продуктивність (Core Web Vitals), крос-доменні запити, обробку помилок.
  7. Документація та передача — записуємо відео-консультацію для команди, передаємо репозиторій.

Терміни: базова інтеграція — від 5 до 7 робочих днів, складні сценарії (GraphQL, ACF, on-demand ISR) — до 15 днів. Точну оцінку даємо після аудиту.

Деталі налаштування CORS

При різних доменах WordPress і фронтенду додаємо фільтр rest_pre_serve_request, який встановлює заголовки для дозволених джерел. Це стандартна практика, описана в документації REST API. Якщо потрібна нестандартна конфігурація — ми підлаштуємо під ваш проєкт.

Скільки коштує інтеграція headless WordPress?

Вартість розраховується індивідуально на основі обсягу контенту, кількості типів записів, необхідності GraphQL та складності маршрутизації. У середньому бюджет порівнянний з місячною зарплатою молодшого розробника, а економія на хостингу та часі розробки перекриває інвестиції протягом півроку.

Хочете отримати точну оцінку? Замовте аудит вашого проєкту — ми проаналізуємо архітектуру і запропонуємо оптимальне рішення. Зв'яжіться з нами через форму на сайті або напишіть у Telegram.