Abstract
Headless WordPress leverages the content creation workflow of the world’s most popular CMS while delivering the frontend performance of React. This chapter dissects the architecture of a production-grade headless system using Next.js and WPGraphQL. We explore the nuances of Data Fetching (SSG vs. ISR), the GraphQL schema, and the essential implementation of “Preview Mode” to maintain editorial velocity.
The Architecture: Decoupled Data
In this stack, WordPress operates strictly as an API source. The WPGraphQL plugin transforms the WordPress database into a queryable GraphQL schema, solving the “over-fetching” problem inherent in the REST API. Instead of receiving a massive JSON blob for a post, the frontend requests only the specific fields it needs (e.g., title, slug, featuredImage), reducing payload size and improving hydration speed.
Data Fetching Strategies in Next.js
Next.js offers two primary methods relevant to WordPress sites:
- Static Site Generation (SSG): Pages are built once at deploy time. This is ultra-fast but impractical for large sites with frequent updates, as a full rebuild takes too long.
- Incremental Static Regeneration (ISR): The 2025 standard for headless WP. ISR allows Next.js to regenerate specific pages in the background after the initial deployment.
ISR Implementation:
// pages/posts/[slug].js
export async function getStaticProps({ params }) {
const data = await getPostBySlug(params.slug);
return {
props: { post: data.post },
// Revalidate this page at most once every 60 seconds
revalidate: 60,
};
}
With revalidate: 60, the first visitor after a minute triggers a background rebuild. The user sees the cached (stale) page, while the next visitor sees the updated content. This “Stale-While-Revalidate” strategy combines the speed of static files with the freshness of dynamic rendering.23
The Missing Link: Preview Mode
A major friction point in headless architectures is the loss of the “Preview” button. Editors need to see draft content before it goes public. Next.js Preview Mode bridges this gap by bypassing the static build generation.
The Preview Workflow:
- WordPress: A plugin generates a signed URL: https://frontend.com/api/preview?secret=TOKEN&id=123.
- Next.js API Route: The route /api/preview validates the token. If valid, it calls res.setPreviewData({}). This sets a special cookie in the browser.
- Page Rendering: When getStaticProps runs, it receives a context.preview boolean. If true, it bypasses the build cache and fetches the draft data from WordPress instead of the published data.
API Route Code:
export default async function handler(req, res) {
const { secret, id, slug } = req.query;
// 1. Security Check
if (secret!== process.env.WORDPRESS_PREVIEW_SECRET ||!id) {
return res.status(401).json({ message: 'Invalid token' });
}
// 2. Fetch the draft post to confirm it exists
const post = await getPreviewPost(id);
if (!post) {
return res.status(401).json({ message: 'Post not found' });
}
// 3. Set Preview Cookie
res.setPreviewData({});
// 4. Redirect to the content
res.redirect(`/posts/${post.slug}`);
}
This implementation restores the WYSIWYG confidence for editors, making the headless transition seamless for non-technical teams.