
Headless WordPress means using WordPress purely as a content backend — writers still work in wp-admin, but the public-facing site is built separately with React, Next.js, or Vue, pulling content through the REST API or GraphQL instead of PHP templates. It’s one of the biggest WordPress architecture shifts happening right now, and for good reason: it decouples content from presentation without giving up the editing experience teams already know.
What Headless WordPress Actually Means
In a traditional WordPress site, PHP templates render HTML on the server for every request. In a headless setup, WordPress’s job shrinks to storing and serving content as JSON — the actual page rendering happens in a separate JavaScript application. WordPress becomes the CMS; something else becomes the front end.
1. Decide Between the REST API and WPGraphQL
WordPress ships with the REST API built in, so it works with zero extra plugins. WPGraphQL (a plugin) gives you a single flexible query instead of multiple REST calls, which front-end frameworks like Next.js tend to prefer for reducing over-fetching.
// REST: fetch the 10 latest posts with featured images
fetch('https://example.com/wp-json/wp/v2/posts?_embed&per_page=10')
.then(res => res.json())
.then(posts => console.log(posts));
2. Expose Custom Fields to the API
Custom fields (from ACF or your own register_post_meta() calls) don’t appear in the REST response by default. You have to explicitly opt them in:
register_post_meta('post', 'subtitle', [
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function () {
return current_user_can('edit_posts');
},
]);
3. Build a Custom Endpoint for Front-End-Shaped Data
Rather than making the React app stitch together several REST calls, build one endpoint that returns exactly the shape the front end needs — post, featured image URL, and related posts in one response.
add_action('rest_api_init', function () {
register_rest_route('headless/v1', '/post/(?P<slug>[a-zA-Z0-9-]+)', [
'methods' => 'GET',
'callback' => function (WP_REST_Request $request) {
$post = get_page_by_path($request->get_param('slug'), OBJECT, 'post');
if (!$post) {
return new WP_Error('not_found', 'Post not found', ['status' => 404]);
}
return new WP_REST_Response([
'title' => get_the_title($post),
'content' => apply_filters('the_content', $post->post_content),
'image' => get_the_post_thumbnail_url($post, 'large'),
'date' => get_the_date('c', $post),
], 200);
},
'permission_callback' => '__return_true',
]);
});
4. Consume It in Next.js
On the front end, fetch the custom endpoint at build time (Static Generation) or request time (Server Components), depending on how often the content changes.
// app/blog/[slug]/page.js
async function getPost(slug) {
const res = await fetch(`https://example.com/wp-json/headless/v1/post/${slug}`, {
next: { revalidate: 3600 }, // ISR: refresh hourly
});
return res.json();
}
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
);
}
5. Trigger Rebuilds When Content Changes
Static front ends need to know when content changes in wp-admin. Fire a webhook to your hosting platform (Vercel, Netlify) on publish/update so the front end rebuilds automatically instead of serving stale content.
add_action('save_post', function ($post_id) {
if (wp_is_post_revision($post_id)) {
return;
}
wp_remote_post('https://api.vercel.com/v1/integrations/deploy/your-hook-id', [
'blocking' => false,
'timeout' => 1,
]);
});
6. Don’t Forget SEO in a Headless Setup
Going headless means the front end — not WordPress — generates the actual <title>, meta tags, and structured data the browser serves. Pull your Rank Math title/description via the REST API (they’re stored as post meta) and render them into the front end’s <head> yourself, or the SEO work you do in wp-admin never reaches real visitors.
When Headless WordPress Is (and Isn’t) Worth It
Headless makes sense when you need a highly interactive, app-like front end, multiple front ends sharing one CMS (web + mobile), or a JavaScript team that doesn’t want to touch PHP templates. It’s usually overkill for a typical content site or WooCommerce store, where a traditional theme with good caching (see our SQL query optimization guide for database-side performance) gets you most of the benefit with far less infrastructure to maintain. If you do go headless, revisit your custom REST API endpoint patterns and your WordPress security checklist together — an API-only backend has a different attack surface than a traditional site, and it’s worth checking the official WordPress REST API Handbook for the latest authentication guidance.
Wrapping Up
Headless WordPress isn’t a replacement for traditional WordPress — it’s a different architecture for a different set of needs. If your team already knows React or Next.js and wants a fast, app-like front end while keeping the editorial workflow WordPress is known for, exposing your content cleanly through the REST API (or WPGraphQL) is a well-trodden path in 2026, not an experimental one.