NetcaneTechnologies

WordPress

Headless WordPress + Next.js: Architecture and Pitfalls

How to structure a headless WordPress front end in Next.js and avoid common pitfalls around data, preview, and deployment.

Yasir Haleem3 min read

Running Next.js against WordPress as a headless CMS works well if you treat WordPress as a content API and handle preview, revalidation, and deployment deliberately.

API choice: REST vs GraphQL

WordPress REST is built-in; WPGraphQL requires a plugin but gives one endpoint and flexible queries. Use REST for simplicity and fewer moving parts; use GraphQL if you want to request exactly the fields you need and avoid over-fetching. Either way, centralize API calls in Next.js (e.g. a lib/wp.ts) with base URL from env and optional auth for draft content. Type the responses so you catch breaking changes when WordPress or plugins change.

Data fetching and caching

Fetch posts and pages in Next.js server components or in getStaticProps/getServerSideProps depending on your Next version. Use ISR (revalidate) so content updates without full rebuilds. When you publish or update a post in WordPress, trigger a revalidate (e.g. webhook to Next.js or Vercel’s deploy hook) so the front end refreshes. Without that, you’ll serve stale content until the next build or revalidate interval.

// lib/wp.ts
const WP_URL = process.env.WP_URL;
export async function getPost(slug: string) {
  const res = await fetch(
    `${WP_URL}/wp-json/wp/v2/posts?slug=${slug}&_embed`,
    { next: { revalidate: 60 } }
  );
  const data = await res.json();
  return Array.isArray(data) ? data[0] : null;
}

Preview and drafts

To preview drafts, you need to call WordPress with authentication (e.g. application password or cookie) and request the draft. Use Next.js preview mode: a route that sets the preview cookie and redirects to the post. In your data layer, when preview mode is on, request the draft from WordPress (e.g. by id with auth) and render that. Don’t expose the WordPress admin or API credentials to the browser; do all draft fetching on the server.

Pitfalls

Stale content: Publish in WordPress but no revalidation → users see old content. Fix: webhook or cron to revalidate. Block content: WordPress stores block markup; you need to parse or render it in Next.js (e.g. custom parser or a shared renderer). Media: Use WordPress media URLs or proxy them; ensure images are optimized (e.g. next/image with WP domain in remotePatterns). Menus and global data: Fetch menus and options (e.g. via REST or GraphQL) and cache them; structure so they’re available where your layout needs them. With this architecture and pitfalls in mind, headless WordPress + Next.js stays manageable.

Summary

Pick REST or GraphQL and centralize calls; use revalidation and webhooks so content isn’t stale. Implement preview on the server with auth. Handle block content, media, and menus explicitly. Avoid exposing WordPress credentials and revalidate after publish. That’s a solid headless WordPress + Next.js setup.

About the author

Yasir Haleem is founder and lead engineer at Netcane Technologies. He builds production Next.js sites with headless CMS platforms — Strapi, Contentful, Sanity, and WordPress — with a focus on performance, SEO, and maintainable architecture.

Let's work together

Tell us about your project. We respond within one business day with a clear scope, timeline, and estimate.