How to Use WordPress as a Headless CMS for Next.js
A practical, SEO-focused setup using WPGraphQL or the WordPress REST API—with ISR, previews, and performance tips

If you love the WordPress editorial experience but want the speed and flexibility of React, pairing WordPress as a headless CMS with Next.js is a powerful move. In this guide, you’ll learn the fastest, production-ready way to connect WordPress to Next.js using either the built-in WordPress REST API or the popular WPGraphQL plugin, then add Incremental Static Regeneration (ISR), secure previews, structured data, and performance best practices.
What you’ll learn
- Pros/cons of REST vs. GraphQL for WordPress
- How to fetch posts/pages with Next.js App Router
- How to wire ISR, on‑demand revalidation, and previews
- How to handle images, ACF, and SEO metadata
- Deploying to Vercel and hardening your setup
- Better performance with pre-rendering via SSG/ISR (see Next.js docs on Incremental Static Regeneration: https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration)
- A secure split—your WordPress admin isn’t serving the public site
- A familiar editor, custom fields, and roles
- Developer-friendly React components, routing, and TypeScript
- WordPress REST API: https://developer.wordpress.org/rest-api/
- WPGraphQL: https://www.wpgraphql.com/
- Next.js App Router: https://nextjs.org/docs/app
- Built in, no plugin required
- Endpoints like /wp-json/wp/v2/posts, /pages, /media
- Simpler onboarding but more requests and potential over‑fetching
- Flexible queries with a typed schema
- Ideal for complex content models and ACF
- Install WPGraphQL + WPGraphQL for ACF
- Docs: https://www.wpgraphql.com/ and ACF: https://www.advancedcustomfields.com/
Why use WordPress as a headless CMS for Next.js
Using WordPress for content and Next.js for the front end gives you:
Learn more about the platform capabilities here:
WordPress REST API vs WPGraphQL (which should you choose?)
Both work great—choose based on complexity and flexibility needs.
REST API (long‑tail keyword: “WordPress REST API with Next.js
WPGraphQL (long‑tail keyword: “WPGraphQL with Next.js App Router
Set up WordPress for headless (long‑tail keyword: “headless WordPress configuration
- Enable pretty permalinks: https://wordpress.org/documentation/article/using-permalinks/
- Decide on API approach (REST or WPGraphQL)
- Use Application Passwords for secure server-to-server requests: https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/
- Optional: Install Advanced Custom Fields (ACF) and expose fields with WPGraphQL for ACF: https://github.com/wp-graphql/wp-graphql-acf
- Keep WordPress updated and harden access
Create your Next.js project (long‑tail keyword: “Next.js headless WordPress setup
- Use the Next.js App Router:
- Docs: https://nextjs.org/docs/app
- Data fetching: https://nextjs.org/docs/app/building-your-application/data-fetching/fetching
Environment variables (example)
- WP_URL=https://your-wp.example.com
- WP_GRAPHQL_ENDPOINT=https://your-wp.example.com/graphql
- NEXT_PUBLIC_SITE_URL=https://your-frontend.example.com
- REVALIDATE_SECRET=your-long-secret
Allow WordPress media domains for optimized images:
next/image docs: https://nextjs.org/docs/app/api-reference/components/image
Fetch content in Next.js (long‑tail keyword: “fetch WordPress content in Next.js
Option 1 — WPGraphQL query pattern
- Install WPGraphQL and verify /graphql is live
- Build a tiny fetcher and query posts by slug
Example (abbreviated)
- Fetcher (POST JSON to your GraphQL endpoint)
- Query posts list (id, slug, title, excerpt, featuredImage)
- Query single post by SLUG (title, content, featured image, ACF SEO fields)
Authoritative references:
- WPGraphQL: https://www.wpgraphql.com/
- Next.js fetch caching and ISR: https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration
Option 2 — REST API query pattern
- List posts: /wp-json/wp/v2/posts?per_page=20
- Get by slug: /wp-json/wp/v2/posts?slug=your-slug
- Use Next.js revalidate for ISR
Reference:
- WordPress REST API: https://developer.wordpress.org/rest-api/
- Add export const revalidate = 60 on lists and 300 on detail pages
- Docs: https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration
Incremental Static Regeneration and instant updates
Static pages are fast, but your editors want instant updates after publishing.
Set route-level revalidate (ISR)
On‑demand revalidation (long‑tail keyword: “WordPress webhook Next.js revalidate
- Create a Next.js route handler that calls revalidatePath
- Trigger it from WordPress on publish via save_post action
- Docs: On‑demand revalidation: https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration#on-demand-revalidation and route handlers: https://nextjs.org/docs/app/building-your-application/routing/route-handlers
Previews for drafts (long‑tail keyword: “Next.js preview mode with WordPress
- Use draftMode in Next.js to bypass cache for authorized preview sessions
- Create an /api/preview endpoint that validates a secret and redirects to /blog/[slug]
- Docs: Next.js Preview Mode: https://vercel.com/docs/nextjs/preview-mode and draftMode: https://nextjs.org/docs/app/api-reference/functions/draftMode
Images, media, and performance
- Use next/image for responsive, lazy-loaded images
- Add WordPress upload domains to next.config.js
- Prefer 1200×630 hero images (OG-ready)
- Optimize Core Web Vitals by pre-rendering content and limiting client-side fetching
Custom Post Types and ACF (long‑tail keyword: “ACF fields in WPGraphQL”)
- Create CPTs and ACF field groups for structured content
- Expose via WPGraphQL for ACF for typed queries
- Map fields to purpose-built React components
- Docs: https://github.com/wp-graphql/wp-graphql-acf
SEO and structured data for headless WordPress
- Use Next.js Metadata API for title, description, canonical, Open Graph, and Twitter cards
- Add schema.org JSON‑LD for Articles
- Include internal links, descriptive headings, and alt text
- Reference: Next.js Metadata: https://nextjs.org/docs/app/building-your-application/optimizing/metadata and Google Article structured data: https://developers.google.com/search/docs/appearance/structured-data/article
Sitemaps and robots
- Generate a simple sitemap.ts in Next.js that lists your home, blog index, and posts
- Add robots.txt and point to your sitemap
- Reference: Google sitemaps overview: https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview
Deploy and harden
- Deploy Next.js to Vercel for global caching, ISR, and previews: https://vercel.com/docs/incremental-static-regeneration
- Host WordPress on a reputable provider, lock down wp-admin, and keep plugins updated
- Configure environment variables securely: https://vercel.com/docs/projects/environment-variables
- If you fetch from the browser, configure CORS carefully (MDN CORS primer: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
Common pitfalls (and how to avoid them)
- No instant updates after publish → Add on‑demand ISR with a WordPress webhook
- Previews returning old content → Ensure draftMode bypasses caches
- Missing images in production → Allowlist your WordPress media domain
- Over-fetching content → Prefer WPGraphQL with precise field queries for complex models
- Slug conflicts across CPTs → Namespace routes (e.g., /blog/[slug] vs /case-studies/[slug])
Quick code snippets (Vocal-friendly, abbreviated)
Minimal WPGraphQL fetcher
- POST JSON to /graphql
- Throw on errors; return data
- Use server-only requests (avoid exposing secrets client-side)
REST post by slug
- GET /wp-json/wp/v2/posts?slug={slug}
- In Next.js, fetch with { next: { revalidate: 300 } }
- H3: On‑demand revalidate endpoint (App Router)
- /api/revalidate?secret=...&path=/blog/my-post
- Validate secret; call revalidatePath(path)
Pro tip: Host long code samples in a GitHub Gist and embed or link from Vocal for a cleaner reading experience.
About the Creator
Anouar Aissaoui
I'm a results-driven Full Stack Web Developer with deep expertise in building high-performance, responsive, and SEO-optimized websites. Backed by years of hands-on experience, I specialize in WordPress development and strategic SEO



Comments
There are no comments for this story
Be the first to respond and start the conversation.