Headless WordPress with Next.js is one of the most powerful ways to use WordPress as a content management system while building a faster, more flexible frontend with React. WordPress handles content, authors, media, categories, tags, custom post types, and editorial workflows. Next.js handles the public website, routing, rendering, caching, performance, components, and deployment.
This setup is useful when you like WordPress for publishing but do not want the frontend limitations of a traditional WordPress theme. With a headless architecture, your editors can continue using WordPress, while developers build the frontend with Next.js, TypeScript, Tailwind CSS, React components, and modern deployment platforms.
But headless WordPress is not automatically better for every site. It adds complexity. You need to handle API fetching, previews, caching, redirects, SEO metadata, image handling, authentication, deployment, webhooks, and plugin compatibility differently.
This guide explains how headless WordPress with Next.js works, when to use it, when to avoid it, and how to build a practical production-ready setup.
TL;DR
```Use headless WordPress with Next.js if you want WordPress as the CMS but need a custom React frontend, better design control, advanced performance tuning, flexible deployment, or a decoupled architecture. Use traditional WordPress if you want simpler maintenance, plugin-powered frontend features, easier previews, and less development overhead.
- Best for: content-heavy sites, SaaS blogs, marketing sites, enterprise publishing, custom frontends, and high-performance builds.
- Use REST API if: your content model is simple and you want fewer dependencies.
- Use WPGraphQL if: you need efficient queries, custom fields, nested data, and a better developer experience.
- Use Next.js App Router: for layouts, Server Components, metadata, caching, and modern routing.
- Plan previews early: draft previews are one of the trickiest parts of headless WordPress.
- Do not go headless just for speed: a well-optimized traditional WordPress site can still be fast.
What Is Headless WordPress?
Headless WordPress means WordPress is used only as the backend CMS, while the frontend is built separately. In a normal WordPress site, WordPress controls both the admin dashboard and the public theme. In a headless setup, WordPress still manages content, but the public website is rendered by another frontend framework such as Next.js.
The “head” is the frontend. Removing it from WordPress gives you a decoupled system:
- WordPress: content management, users, posts, pages, media, categories, tags, custom post types, custom fields, editorial workflow.
- Next.js: frontend rendering, routes, components, caching, layouts, SEO metadata, image handling, deployment, and user experience.
WordPress sends content through an API. Next.js fetches that content and displays it through React components.
Why Use Next.js with WordPress?
Next.js is a strong frontend choice because it supports modern React development, file-based routing, server rendering, static generation, dynamic routes, streaming, caching, API routes, metadata handling, and deployment-friendly performance patterns.
For WordPress projects, Next.js is useful when you need:
- A custom frontend that does not depend on a WordPress theme.
- Better control over Core Web Vitals.
- Reusable React components.
- Design systems with Tailwind CSS or component libraries.
- Custom landing pages and content templates.
- Static or cached content delivery.
- Separate frontend and backend deployment.
- Integration with external APIs, CRMs, apps, and product data.
This is especially useful for teams that want WordPress publishing plus a modern JavaScript frontend.
How Headless WordPress with Next.js Works
The basic flow is simple:
- Editors create content inside WordPress.
- WordPress exposes that content through REST API or GraphQL.
- Next.js fetches the content during build time, request time, or revalidation.
- Next.js renders the page using React components.
- The frontend is deployed separately from WordPress.
A typical architecture looks like this:
Editor → WordPress Admin → REST API or WPGraphQL → Next.js Frontend → Visitor
WordPress remains the editorial backend. Next.js becomes the public website.
REST API vs WPGraphQL
You can connect Next.js to WordPress using the built-in REST API or the WPGraphQL plugin. Both can work, but they fit different projects.
| Option | Best For | Pros | Cons |
|---|---|---|---|
| WordPress REST API | Simple blogs, pages, posts, categories, tags, basic content sites | Built into WordPress, no GraphQL dependency, easy to test | Can require multiple requests for nested or custom data |
| WPGraphQL | Custom fields, complex content models, nested queries, developer-heavy projects | Efficient queries, better control over returned fields, strong developer experience | Requires plugin setup and GraphQL knowledge |
Use REST API if the site is simple and your content structure is straightforward. Use WPGraphQL if you need cleaner data fetching for custom post types, relationships, custom fields, menus, author data, and nested content structures.
When Headless WordPress Is a Good Choice
Headless WordPress is a good fit when the frontend needs more control than a normal theme can provide.
It works well for:
- SaaS blogs and marketing sites.
- High-performance content websites.
- Enterprise publishing platforms.
- Custom React frontends.
- Multichannel content delivery.
- Websites with design systems.
- Teams with separate frontend and content workflows.
- Sites that need integration with external APIs.
- Large content libraries with custom templates.
If WordPress is mainly your content database and you want full frontend freedom, headless makes sense.
When You Should Avoid Headless WordPress
Headless WordPress is not always the best decision. Many sites are better served by a traditional WordPress theme or block theme.
Avoid headless WordPress if:
- You do not have a developer or technical team.
- You rely heavily on plugins that render frontend features automatically.
- You want the simplest WordPress maintenance workflow.
- You need easy visual editing of the full frontend.
- Your site is a basic blog or small business site.
- You do not want to manage two deployments.
- You need plugin-based forms, SEO, memberships, or ecommerce to work instantly on the frontend.
For many WordPress users, Full Site Editing or a clean block theme is simpler. Read Full Site Editing with Gutenberg: Practical Guide if you want more control without going fully headless.
Headless WordPress Project Structure
A typical setup has two separate applications:
/wordpress-backend
WordPress admin
Posts, pages, media, users
REST API or WPGraphQL
Plugins for CMS features
/nextjs-frontend
Next.js app
React components
Routes
Data fetching
Metadata
Styling
Deployment
The backend can live on a subdomain such as:
cms.example.com
The frontend can live on the main domain:
example.com
This separation keeps the public user experience independent from the WordPress theme layer.
Basic Setup Steps
Step 1: Prepare WordPress
Start with a clean WordPress installation. You do not need a complex theme because the public frontend will be handled by Next.js.
Configure:
- Permalinks.
- Posts and pages.
- Categories and tags.
- Media uploads.
- Custom post types if needed.
- Custom fields if needed.
- REST API or WPGraphQL access.
If you use custom fields, Advanced Custom Fields plus WPGraphQL support is a common developer workflow.
Step 2: Decide Between REST API and GraphQL
For REST API, WordPress exposes endpoints like:
https://cms.example.com/wp-json/wp/v2/posts
https://cms.example.com/wp-json/wp/v2/pages
https://cms.example.com/wp-json/wp/v2/categories
For WPGraphQL, your endpoint is usually:
https://cms.example.com/graphql
GraphQL lets you request only the fields you need, which can make templates cleaner for complex content models.
Step 3: Create the Next.js App
Create a new Next.js project:
npx create-next-app@latest next-wordpress-site
For most modern builds, choose:
- TypeScript.
- App Router.
- ESLint.
- Tailwind CSS if you want utility-first styling.
- A clean
srcdirectory if your team prefers it.
Step 4: Add Environment Variables
Create an environment file for the WordPress API URL:
WORDPRESS_API_URL=https://cms.example.com/wp-json/wp/v2
WORDPRESS_GRAPHQL_URL=https://cms.example.com/graphql
Do not hardcode API URLs in every component. Keep them in environment variables so staging and production can use different backends.
Fetching WordPress Posts with REST API
A simple REST API fetch in a Next.js Server Component may look like this:
async function getPosts() {
const res = await fetch(`${process.env.WORDPRESS_API_URL}/posts?_embed`, {
next: { revalidate: 300 }
});
if (!res.ok) {
throw new Error('Failed to fetch posts');
}
return res.json();
}
export default async function BlogPage() {
const posts = await getPosts();
return (
<main>
<h1>Blog</h1>
{posts.map((post) => (
<article key={post.id}>
<h2 dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
<div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
</article>
))}
</main>
);
}
This fetches posts from WordPress and revalidates periodically. For production, you should sanitize rendered HTML, handle errors gracefully, and map WordPress data into cleaner TypeScript types.
Fetching WordPress Posts with WPGraphQL
A basic GraphQL query can request exactly the fields your template needs:
const query = `
query GetPosts {
posts {
nodes {
id
title
slug
excerpt
date
}
}
}
`;
async function getPosts() {
const res = await fetch(process.env.WORDPRESS_GRAPHQL_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ query }),
next: { revalidate: 300 }
});
if (!res.ok) {
throw new Error('Failed to fetch posts');
}
const json = await res.json();
return json.data.posts.nodes;
}
WPGraphQL becomes more useful as the project grows. It can reduce over-fetching, simplify nested relationships, and make custom content templates easier to manage.
Creating Dynamic Routes for WordPress Posts
In Next.js App Router, a blog post route may look like this:
app/blog/[slug]/page.tsx
Your page can fetch a post by slug:
async function getPost(slug: string) {
const res = await fetch(
`${process.env.WORDPRESS_API_URL}/posts?slug=${slug}&_embed`,
{ next: { revalidate: 300 } }
);
if (!res.ok) {
throw new Error('Failed to fetch post');
}
const posts = await res.json();
return posts[0] || null;
}
export default async function PostPage({ params }) {
const post = await getPost(params.slug);
if (!post) {
return <h1>Post not found</h1>;
}
return (
<article>
<h1 dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
<div dangerouslySetInnerHTML={{ __html: post.content.rendered }} />
</article>
);
}
For a real production site, add proper 404 handling, metadata generation, canonical URLs, structured data, and content sanitization.
SEO in Headless WordPress
SEO is one of the most important parts of a headless WordPress build. In a traditional WordPress site, SEO plugins often output titles, meta descriptions, canonical tags, schema, Open Graph tags, and sitemaps directly into the theme. In a headless setup, your Next.js frontend must handle much of that output.
You need a plan for:
- Meta titles.
- Meta descriptions.
- Canonical URLs.
- Open Graph images.
- Twitter/X card metadata.
- Article schema.
- Breadcrumb schema.
- XML sitemaps.
- Robots.txt.
- Redirects.
- Pagination.
- Category and tag archives.
Next.js metadata handling can generate page-level metadata from WordPress content. For example, you can fetch SEO fields from WordPress and return them from a metadata function.
If you use an SEO plugin on WordPress, check whether its metadata is available through REST API or GraphQL. Some plugins need add-ons or custom fields to expose SEO data properly in a headless setup.
Handling Images and Media
WordPress media files usually remain on the WordPress backend or a CDN. Next.js can render those images on the frontend, but you need to configure image domains and handle image sizes carefully.
Important image considerations:
- Use featured images consistently.
- Expose alt text through the API.
- Use optimized image sizes instead of original uploads when possible.
- Configure remote image domains in Next.js.
- Use a CDN for media-heavy sites.
- Avoid rendering massive original images on listing pages.
Do not assume headless automatically fixes image performance. A headless site with oversized media can still fail Core Web Vitals.
Caching and Revalidation
Caching is where Next.js becomes powerful, but it must be planned carefully. WordPress content changes when editors publish, update, delete, or schedule posts. Your frontend cache needs to know when to refresh.
Common strategies include:
- Time-based revalidation: refresh content every few minutes.
- On-demand revalidation: trigger a cache refresh when WordPress content changes.
- Cache tags: group cached content and invalidate related pages.
- Webhook-based publishing: WordPress sends a request to Next.js after content updates.
For simple blogs, time-based revalidation may be enough:
fetch(url, {
next: { revalidate: 300 }
});
For serious publishing sites, use on-demand revalidation so updates appear quickly after editors publish changes.
Draft Previews and Editorial Workflow
Previews are one of the hardest parts of headless WordPress. In normal WordPress, editors click Preview and WordPress shows the draft through the active theme. In headless WordPress, the preview needs to open in Next.js, fetch draft content securely, and show unpublished content only to authorized users.
A good preview setup should:
- Allow editors to preview drafts before publishing.
- Use secure preview URLs.
- Authenticate private content requests.
- Avoid exposing draft content publicly.
- Work for posts, pages, custom post types, and revisions if needed.
Plan previews before building the whole site. Adding them late can be painful.
Authentication and Private API Requests
Public content can often be fetched without authentication. Private content, drafts, previews, users, protected fields, and write operations require authentication.
Common options include:
- Application Passwords for server-side API authentication.
- JWT authentication through a plugin or custom setup.
- OAuth for more advanced integrations.
- Custom preview tokens for draft previews.
Never expose WordPress API credentials in client-side JavaScript. Keep secrets on the server side through environment variables and backend-only functions.
Security Considerations
Headless does not make WordPress automatically secure. The WordPress backend still needs normal security hardening.
Secure the WordPress backend with:
- Strong admin passwords.
- Two-factor authentication.
- Limited admin accounts.
- Regular updates.
- Restricted login attempts.
- Backups.
- Security headers.
- Private debug logging.
- Protected API credentials.
- Careful plugin selection.
Use the FyrePress Security Headers Generator and wp-config.php Builder to prepare safer WordPress configuration baselines.
Plugin Compatibility in Headless WordPress
This is one of the biggest surprises for beginners. Many WordPress plugins are built to output frontend HTML, scripts, forms, styles, shortcodes, or widgets inside a WordPress theme. In a headless setup, those frontend outputs may not appear automatically in Next.js.
Plugin types that often need extra work include:
- SEO plugins.
- Form plugins.
- Page builders.
- Membership plugins.
- WooCommerce extensions.
- Shortcode-based plugins.
- Table plugins.
- Gallery plugins.
- Review plugins.
- Schema plugins.
Before choosing headless, list every plugin the site depends on and confirm how its data will reach Next.js.
WooCommerce and Headless WordPress
Headless WooCommerce is possible, but it is more complex than a headless blog. Product pages are only one part of ecommerce. You also need cart behavior, checkout, payment gateways, taxes, shipping, customer accounts, order emails, inventory, coupons, webhooks, analytics, and fraud handling.
Use headless WooCommerce only if you have a clear technical reason and the team to support it.
For many stores, traditional WooCommerce is simpler. Read WooCommerce vs Shopify: Which Should You Pick? if you are still deciding your ecommerce stack.
Deployment Architecture
A production setup usually has separate hosting for WordPress and Next.js.
| Layer | Common Hosting Choice | Responsibility |
|---|---|---|
| WordPress backend | Managed WordPress hosting, VPS, cloud server | CMS, database, media, admin, APIs |
| Next.js frontend | Vercel, Netlify, cloud hosting, Node server | Public website, routes, rendering, cache, components |
| CDN | Cloudflare or platform CDN | Static assets, cache, edge delivery, security rules |
Keep WordPress stable and private where possible. The public site should run through Next.js, while the WordPress admin can live on a protected subdomain.
Production Checklist
Before launching a headless WordPress and Next.js site, check the full stack.
- WordPress REST API or GraphQL endpoint works.
- Posts, pages, categories, tags, and media fetch correctly.
- Custom post types are exposed correctly.
- SEO metadata is rendered by Next.js.
- Canonical URLs are correct.
- Open Graph images work.
- XML sitemap includes frontend URLs, not backend-only URLs.
- Robots.txt is configured correctly.
- Redirects from old WordPress URLs are handled.
- Draft previews are secure and working.
- Images are optimized.
- API credentials are not exposed client-side.
- WordPress backend is secured.
- Revalidation works after publishing.
- 404 pages and empty states work.
- Analytics and tracking scripts are installed correctly.
- Error logs are monitored after launch.
Common Mistakes to Avoid
- Going headless only because it sounds modern.
- Underestimating preview complexity.
- Forgetting that SEO plugin output does not automatically appear on the Next.js frontend.
- Fetching too much data from REST API on every request.
- Not planning cache invalidation after publishing.
- Exposing API credentials in the browser.
- Assuming all WordPress plugins work normally in headless mode.
- Ignoring image optimization.
- Using WordPress-rendered HTML without sanitization.
- Forgetting redirects, sitemaps, and canonical URLs during migration.
Headless WordPress vs Traditional WordPress
| Category | Headless WordPress with Next.js | Traditional WordPress |
|---|---|---|
| Frontend control | Very high | Depends on theme and builder |
| Setup complexity | Higher | Lower |
| Editor previews | Requires custom setup | Built in |
| Plugin frontend output | Often requires custom integration | Usually works directly |
| Performance control | High with proper caching | High with good optimization |
| Maintenance | Two systems to maintain | One main system |
| Best for | Custom React frontends and complex digital products | Blogs, business sites, stores, and normal WordPress builds |
Final Verdict
Headless WordPress with Next.js is a strong choice when you want WordPress as the CMS and Next.js as the frontend framework. It gives you frontend freedom, React components, modern routing, strong performance patterns, and flexible deployment.
But it is not a shortcut. You must handle API fetching, caching, previews, SEO, redirects, media, authentication, deployment, and plugin compatibility with more care than a traditional WordPress site.
Choose headless WordPress with Next.js if you have a real need for a custom frontend, a developer-friendly architecture, and a decoupled publishing workflow. Choose traditional WordPress if you want simpler maintenance, easier plugin compatibility, and a faster non-developer workflow.
The best setup is the one that matches your team. Headless WordPress is powerful when you have the skill to maintain it. Traditional WordPress is still better when simplicity, plugin compatibility, and editorial convenience matter more.
FAQs About Headless WordPress with Next.js
```What is headless WordPress?
Headless WordPress means WordPress is used as the backend CMS while the public frontend is built separately with a framework such as Next.js. WordPress manages content, and Next.js renders the website.
Is Next.js good for headless WordPress?
Yes. Next.js is a strong choice for headless WordPress because it supports React components, server rendering, static generation, dynamic routing, caching, metadata handling, and modern deployment workflows.
Should I use REST API or WPGraphQL for headless WordPress?
Use the WordPress REST API for simpler sites with basic posts and pages. Use WPGraphQL for complex content models, custom fields, nested relationships, and cleaner developer-focused queries.
Is headless WordPress faster than normal WordPress?
It can be faster, but only if it is built properly. Headless WordPress still needs good caching, optimized images, clean API queries, good hosting, and careful frontend performance work.
Do WordPress plugins work in a headless setup?
Some plugins work well because they store data in WordPress. Others do not automatically work because they rely on WordPress theme output, shortcodes, scripts, or frontend rendering. Always check plugin compatibility before going headless.
How do previews work in headless WordPress?
Previews require a custom setup where WordPress sends the draft preview request to Next.js. The frontend must securely fetch unpublished content and show it only to authorized users.
Is headless WordPress good for SEO?
Yes, but SEO must be implemented on the Next.js frontend. You need to handle meta titles, descriptions, canonical tags, Open Graph data, schema, sitemaps, redirects, pagination, and structured content manually or through custom integrations.
Should small websites use headless WordPress?
Usually no. Small blogs, simple business sites, and brochure websites are often better with traditional WordPress, Full Site Editing, or a lightweight theme because they need less development and maintenance.
```