ThemesCorners
Blog
12 min readby ThemesCorners

Headless WordPress with Next.js — The Pragmatic Guide

When to go headless, when not to, and the exact stack we use when we say yes.

We get this question once a week: "Should we make our WordPress site headless with Next.js?" The honest answer is "probably not, but here is when yes and how." This post is that answer in full.

What "headless" actually means

In a traditional WordPress setup, WordPress generates the HTML that visitors see. The same PHP that runs the admin also renders the public pages.

In a headless setup, WordPress only serves data — through the REST API or WPGraphQL. A separate frontend (Next.js, Astro, SvelteKit, Nuxt — but most commonly Next.js) fetches that data and renders the public site.

You keep:

  • The WordPress editor experience for content authors
  • Plugin ecosystem for backend functionality (WooCommerce, ACF, etc.)

You give up:

  • Live preview that "just works"
  • Most frontend WordPress plugins (page builders, cookie banners, popups)
  • Some SEO plugins' frontend output (you have to re-implement)

You gain:

  • Significantly faster public site (typically 60–80% LCP improvement)
  • Modern developer workflow (TypeScript, hot reload, component libraries)
  • Decoupled deployment — frontend and backend ship independently
  • Frontend can be deployed to any modern host (Vercel, Netlify, Cloudflare Pages)

When to go headless

Honest scenarios where the math works:

Yes — high-traffic publication or content site

If you publish a lot, get a lot of traffic, and need to optimise for Core Web Vitals, headless wins. The performance gap between cached PHP WordPress and a properly built Next.js frontend is real and measurable.

Yes — multi-channel content (web + mobile app + voice)

If you also feed the same content to a mobile app, smart speakers, or partner integrations, headless lets you serve all consumers from the same API. Trying to extract data from a traditional WordPress install for non-web use is painful.

Yes — design system requires React components

If your brand has a React component library and you want WordPress content to render through it, headless is the cleanest answer.

Maybe — corporate site with strong dev team

If you have engineers who know React and would rather work in Next.js than in PHP, headless is reasonable even without the performance argument. Your developer happiness is a real input.

When NOT to go headless

Equally honest:

No — typical small business website

If your site is a 20-page brochure with a blog and a contact form, headless is more work than it is worth. The traditional WordPress + good theme combination gets to 90% of the headless performance at 10% of the complexity.

No — WooCommerce store

This is the hardest case. WooCommerce has hundreds of frontend touchpoints — cart updates, checkout flows, payment gateway integrations, subscription management. Re-implementing all of that in a headless frontend is months of work, and you will get something subtly worse than what WooCommerce ships out of the box. Use WooCommerce Blocks instead.

No — editors who rely on live preview

If your authors live in the live preview ("change a word, refresh, see it"), headless will frustrate them. Preview in headless setups always lags slightly — by design.

No — heavy plugin dependency

Look at your active plugins. Do you depend on any that inject frontend output (Yoast UI tweaks, page builder runtime, Mailchimp popups, chat widgets)? Each one is a separate migration task in headless. If you have more than five, the migration cost balloons.

The stack we use

When we do say yes to headless, here is the exact stack:

Backend (WordPress)

  • WordPress with the editor, WPGraphQL, and minimal frontend plugins.
  • Advanced Custom Fields with the ACF + WPGraphQL bridge for structured content.
  • WP Migrate DB Pro or similar for environment sync.
  • No frontend plugins. Disable anything that generates HTML for the public site — there is no public site for WordPress to render.
  • Hosted on a small managed WP plan ($20–35/month is plenty — load is much lower).

Frontend (Next.js)

  • Next.js 16+ with App Router and Cache Components.
  • TypeScript, Tailwind CSS v4, shadcn/ui for components.
  • next-mdx-remote if some content lives in MDX alongside WordPress.
  • Hosted on Vercel (or Cloudflare Pages, or Netlify).

Caching strategy

The trickiest part. Headless caching is layered:

  1. Static generation for pages that change rarely (about, contact, archive).
  2. Cache Components (Next 16) for pages that change occasionally with a per-page tag.
  3. On-demand revalidation triggered by WordPress webhooks — when a post is published, hit a Next.js endpoint that calls revalidateTag('post-123').
  4. Background refresh for the homepage and high-traffic pages via cron.

Authentication for previews

The only way to make preview not awful is to set up authenticated preview routes:

// app/preview/route.ts
import { draftMode } from 'next/headers';

export async function GET(req: Request) {
  const url = new URL(req.url);
  const secret = url.searchParams.get('secret');
  const slug = url.searchParams.get('slug');
  if (secret !== process.env.PREVIEW_SECRET) {
    return new Response('Invalid token', { status: 401 });
  }
  draftMode().enable();
  return Response.redirect(new URL(`/blog/${slug}`, req.url));
}

Then add a custom button in the WordPress admin that points at /preview?secret=...&slug=... per post.

The migration sequence

For an existing site you want to take headless:

  1. Audit content types. Catalog every post type, custom field, and taxonomy that needs to render. Anything missing from this list will be missing on the new frontend.
  2. Audit frontend plugins. Make a list of every plugin that emits HTML, JS, or CSS to the public site. Each one is a re-implementation task.
  3. Build the frontend in parallel. Next.js site on a subdomain (e.g., next.example.com), full content rendering, no traffic yet.
  4. Run both in parallel for at least 30 days. Compare analytics, conversion rates, error rates side by side.
  5. Switch DNS only after parity is proven. Keep WordPress's wp-admin accessible on admin.example.com.
  6. Monitor for 90 days before declaring success. Some breakage only shows up on quarterly tasks.

The honest summary

Headless WordPress is a wonderful technology for the small number of sites that actually need it. For everyone else, a well-built traditional WordPress site with a fast theme (like ours) gets you 90% of the benefits at a fraction of the complexity.

Decide based on the actual editorial workflow and the actual performance gap — not because headless sounds more modern. It is more modern. It is also more work.

Related articles