Ilija Tošković

LinkedIn
GitHub
Daily.Dev
Written in English

Headless WordPress: Using WP as a Backend for React or Next.js

WordPress as a backend on the left connected by a GraphQL and REST API layer to a React and Next.js frontend on the right

Headless WordPress means keeping WordPress for what it is genuinely good at — writing, editing, media, roles, workflow — and throwing away the part that renders HTML. The theme goes, PHP templates go, and a React or Next.js application reads the content over an API and renders it instead.

It is a good architecture. It is also oversold. Having built both headless sites and plenty of conventional ones, this is what the trade actually looks like.

What "Headless" Actually Changes

In a normal WordPress site, one PHP request does everything: fetch the content, run it through a theme template, return HTML. Content and presentation live in the same codebase and ship together.

Decoupled, that single request becomes two systems:

WordPress as the content backend on the left, connected through REST or GraphQL to a Next.js or React frontend on the right

The editor still logs into /wp-admin and sees the interface they know. What changed is that WordPress no longer draws the page. It hands over JSON, and your frontend decides what to do with it.

When It Is Worth It

Headless earns its extra complexity in a few specific situations:

  • The frontend is an application, not a brochure. If you already need React for a configurator, a dashboard or heavy interactivity, serving that from a PHP theme is the awkward option.
  • One content source, several frontends. A website, a mobile app and an in-store display reading the same posts. This is the strongest case by far.
  • The design is genuinely custom and performance is a hard requirement. A well-built Next.js frontend with static generation will beat almost any theme, because you are shipping pre-rendered HTML with no plugin CSS or jQuery attached.
  • Your team writes JavaScript, not PHP. A real consideration. The stack people know is the stack they maintain well.

When It Is Not

Be equally honest about the other side:

  • A marketing site with a content team that expects to see what they are editing. Preview is the single biggest thing you lose, and the usual reason clients become unhappy six weeks in.
  • A budget that assumed a theme. Headless is two codebases, two deployments and two sets of dependencies. It costs more to build and more to keep running.
  • Heavy reliance on plugins that render output. This is the one people underestimate, so it gets its own section below.
  • A small brochure site. A good block theme will be fast enough, cost a third as much, and any WordPress developer can pick it up later.

REST API or WPGraphQL?

Two ways to get the content out.

The REST API

Built into WordPress core since 4.7, nothing to install. Content is at /wp-json/wp/v2/:

// app/blog/[slug]/page.tsx
const res = await fetch(
  `${process.env.WP_URL}/wp-json/wp/v2/posts?slug=${slug}&_embed`,
  { next: { revalidate: 3600 } }
);
const [post] = await res.json();

It is dependable and needs no extra plugin. The cost is shape: you get the endpoint's idea of a post, not yours. Fetching a post with its author, featured image, categories and a few custom fields usually means either _embed (which returns far more than you asked for) or several round trips.

WPGraphQL

The alternative is WPGraphQL by Jason Bahl. It is worth knowing where this plugin now sits: it is a canonical plugin on WordPress.org with support from Automattic, which is a meaningful change from its earlier life as a community project — it is no longer a bet on one maintainer's spare time.

You ask for exactly the fields you want, in one request:

query PostBySlug($slug: ID!) {
  post(id: $slug, idType: SLUG) {
    title
    content
    date
    featuredImage { node { sourceUrl altText } }
    author { node { name } }
    categories { nodes { name slug } }
  }
}

The ecosystem around it is the real argument. Three extensions you will reach for, with their exact names, because searching for approximations wastes an afternoon:

Need Plugin Author
ACF fields in the schema WPGraphQL for ACF Jason Bahl
Yoast meta, canonicals, OG tags WPGraphQL Yoast SEO Addon ash_hitch
Query caching and invalidation WPGraphQL Smart Cache Jason Bahl

That last one matters more than it sounds. A GraphQL endpoint hit on every request is a PHP request on every request, and you have just rebuilt the performance problem you left WordPress to escape.

Which to pick

REST if the content model is simple and you want zero extra plugins. WPGraphQL as soon as ACF is involved, because assembling a page from nested custom fields over REST turns into a waterfall of requests very quickly.

The Four Things That Go Wrong

1. Preview

In a themed site, preview is free. Decoupled, there is no preview until you build one: the frontend has to accept a draft token, fetch unpublished content, and render it in a draft-aware route. Next.js has Draft Mode for exactly this, and Faust.js — WP Engine's Next.js toolkit for headless WordPress — ships preview along with authentication, a template hierarchy and block-to-component mapping.

Decide this before you quote the project, not after the first editor asks why the preview button is broken.

2. Plugins that render output

A plugin that stores data is fine. A plugin that renders HTML, enqueues CSS or prints a shortcode is not, because nothing on the frontend runs PHP.

Contact Form 7, most slider and gallery plugins, popup builders, anything that produces markup — all of it stops at the API boundary. You rebuild that functionality in React or drop it. This is the cost people underestimate most. Before committing, go through the client's plugin list and sort it into "stores data" and "renders output". The second column is your real scope.

3. Rebuilding what the theme gave you free

Headless hands you an empty project. Sitemaps, canonical URLs, redirects, 404 handling, RSS, breadcrumbs, pagination, schema markup — all of that came with the theme and a plugin. Now it is yours to implement in Next.js. None of it is hard; all of it is hours.

4. Two systems to host, secure and update

You now run a WordPress install and a Node application. Two deploy pipelines, two dependency trees, two sets of security updates. And WordPress is still on the public internet unless you lock it down — restrict /wp-admin, rate-limit or authenticate the API, and keep it patched. A headless backend that nobody looks at is a backend that nobody notices has been compromised.

Making It Fast

The architecture does not make a site fast on its own. What makes it fast is not hitting WordPress at request time.

In the Next.js App Router, cache the fetch and revalidate on a schedule:

const res = await fetch(`${process.env.WP_URL}/wp-json/wp/v2/posts`, {
  next: { revalidate: 3600, tags: ["posts"] },
});

Then have WordPress tell the frontend when something actually changed, rather than waiting an hour:

// functions.php — ping the frontend when a post is saved
add_action( 'save_post', function ( $post_id, $post ) {
    if ( wp_is_post_revision( $post_id ) || 'publish' !== $post->post_status ) {
        return;
    }

    wp_remote_post( 'https://example.com/api/revalidate', [
        'timeout' => 5,
        'blocking' => false,
        'body'    => [
            'secret' => REVALIDATE_SECRET,
            'slug'   => $post->post_name,
        ],
    ] );
}, 10, 2 );

The route on the other end calls revalidateTag('posts') or revalidatePath(). Editors publish, the page updates within seconds, and visitors still get static HTML. Set blocking to false so a slow frontend never hangs the editor's save.

A Comparison, Honestly

Classic WordPress Headless + Next.js
Build cost Lower Higher, roughly 1.5–2×
Hosting One PHP host WordPress + a Node host
Raw performance Good with caching Excellent, statically generated
Editor preview Free Must be built
Plugin ecosystem All of it Data plugins only
Who can maintain it Any WP developer A JS developer, plus WP knowledge
Multiple frontends No Yes, the main reason to do it
SEO plumbing Plugin handles it You implement it

Frequently Asked Questions

Is headless WordPress faster than a normal WordPress site?

Usually yes, but not because it is headless. It is faster because the frontend is statically generated and ships none of the plugin CSS and JavaScript a theme accumulates. A well-cached conventional site with a lean custom theme can get close. If speed is the only goal, fixing the existing theme is cheaper than rebuilding the whole frontend.

Can I still use Elementor or a page builder with headless WordPress?

Not meaningfully. Page builders produce HTML and CSS rendered by PHP on the frontend, which is precisely the layer you removed. The content model for a headless site should be structured data — custom fields and blocks — not builder markup.

What happens to SEO plugins like Yoast?

Yoast still runs in the admin and still stores your titles, descriptions and canonicals, but it cannot output them, because it never renders your pages. The WPGraphQL Yoast SEO Addon exposes that data in the GraphQL schema so your Next.js frontend can put it into the document head itself. Sitemaps are the same story: Yoast's sitemap describes the WordPress install, not your frontend, so you generate your own.

Do I need WPGraphQL, or is the REST API enough?

The REST API is enough for a simple content model and has the advantage of being in core. Once Advanced Custom Fields is involved, or a page is assembled from several related content types, WPGraphQL saves you a waterfall of requests and a lot of glue code. Most projects of any size end up on WPGraphQL.

Should I make an existing WordPress site headless?

Rarely, on its own. Rebuilding a working site as headless is a full frontend rewrite with no new features to show for it. It makes sense when you are redesigning anyway, or when a second frontend such as a mobile app has appeared. If the complaint is only that the site is slow, audit it first — the problem is usually a page builder, unoptimised images or missing caching, and all three are far cheaper to fix.

In Short

Headless WordPress is the right call when you need one content source feeding more than one frontend, or when the frontend is genuinely an application. It is the wrong call when it is chosen because it sounds modern, on a brochure site with a content team who just want to see their changes before they publish.

If you are weighing this up for a specific project, that decision is part of what I do — including saying when a good theme is the better answer.