Headless WordPress is transforming how developers build web experiences. By decoupling the frontend and backend, it offers superior flexibility, speed, and control. This guide walks you through creating a headless WordPress site using WPGraphQL and Next.js in 2025, helping you harness the full power of a modern web stack.
What is Headless WordPress?
In a traditional WordPress setup, your themes and plugins render the frontend through PHP. A headless approach decouples this entirely. WordPress acts only as a content management backend, while a separate frontend—like one built with React, Vue, or in our case, Next.js—renders the content.
Benefits:
- Performance: Static site generation (SSG) improves loading speed and scalability.
- Security: The public site doesn’t expose WordPress admin endpoints.
- Scalability: Easily integrate with microservices and APIs.
- Flexibility: Use modern tools and frameworks for UX.
Why WPGraphQL and Next.js?
WPGraphQL is a free plugin that adds a GraphQL server to WordPress, allowing structured data fetching.
Next.js is a React framework supporting SSR and SSG, essential for SEO and performance.
Together, they:
- Enable cleaner, faster API queries.
- Support rendering content statically or dynamically.
- Allow developers to use modern frontend architectures.
Prerequisites
- A local WordPress site (via LocalWP or similar).
- Node.js and npm installed.
- Basic knowledge of React and GraphQL.
Step 1: Set Up WordPress Backend
- Install WordPress locally.
- Go to Settings > Permalinks and set to “Post name”.
- Install and activate these plugins:
- WPGraphQL
- WPGraphQL for Advanced Custom Fields (if needed)
- Create some posts, pages, and optionally custom post types.
Step 2: Create Next.js App
- Initialize a new app:
npx create-next-app headless-wp
cd headless-wp
- Install dependencies:
npm install @apollo/client graphql
- Create
.env.local
and add:
NEXT_PUBLIC_WORDPRESS_API_URL=http://localhost:10003/graphql
Step 3: Set Up Apollo Client
Create a new file: lib/apollo.js
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: process.env.NEXT_PUBLIC_WORDPRESS_API_URL,
cache: new InMemoryCache()
});
export default client;
Step 4: Query Posts from WordPress
Create GraphQL query: lib/queries.js
import { gql } from '@apollo/client';
export const GET_POSTS = gql`
query GetPosts {
posts {
nodes {
id
title
slug
excerpt
}
}
}
`;
Create pages/index.js
:
import client from '../lib/apollo';
import { GET_POSTS } from '../lib/queries';
export default function Home({ posts }) {
return (
<div>
<h1>Recent Posts</h1>
<ul>
{posts.map(post => (
<li key={post.id}>
<a href={`/posts/${post.slug}`}>{post.title}</a>
</li>
))}
</ul>
</div>
);
}
export async function getStaticProps() {
const { data } = await client.query({ query: GET_POSTS });
return {
props: { posts: data.posts.nodes },
revalidate: 10
};
}
Step 5: Create Dynamic Post Pages
- Create
pages/posts/[slug].js
import client from '../../lib/apollo';
import { gql } from '@apollo/client';
const GET_POST = gql`
query GetPost($slug: ID!) {
post(id: $slug, idType: SLUG) {
title
content
}
}
`;
export default function Post({ post }) {
return (
<div>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</div>
);
}
export async function getStaticPaths() {
const { data } = await client.query({
query: gql`
query AllSlugs {
posts {
nodes {
slug
}
}
}
`
});
const paths = data.posts.nodes.map(post => ({ params: { slug: post.slug } }));
return {
paths,
fallback: true
};
}
export async function getStaticProps({ params }) {
const { data } = await client.query({
query: GET_POST,
variables: { slug: params.slug }
});
return {
props: {
post: data.post
},
revalidate: 10
};
}
Step 6: Add SEO Tags
Use next/head
in each page:
import Head from 'next/head';
<Head>
<title>{post.title}</title>
<meta name="description" content={post.excerpt} />
</Head>
Step 7: Deploy to Vercel
- Push to GitHub.
- Go to Vercel and import the repo.
- Set your environment variable:
NEXT_PUBLIC_WORDPRESS_API_URL
- Click deploy.
Optimization Tips
- Use Incremental Static Regeneration (ISR).
- Use CDN caching (Vercel does this automatically).
- Enable image optimization with
next/image
. - Monitor performance with Google PageSpeed Insights.
Internal Resources
- Learn how to Speed Up WordPress Admin
- Fix WordPress White Screen of Death
- Check out Advanced WordPress Cleanup Services
External Resources
Conclusion
Building a headless WordPress site using WPGraphQL and Next.js empowers developers with flexibility, performance, and scalability. As more businesses demand lightning-fast experiences and modern UIs, this architecture becomes increasingly relevant. Follow this 2025 guide to create future-proof, maintainable, and high-performing WordPress sites.