WordPress powers over 40% of the web. But the traditional WordPress model—PHP rendering HTML on every request—does not always match modern frontend requirements. When you need a React or Next.js frontend with WordPress as the content backend, headless WordPress with GraphQL is the established pattern.
The idea: WordPress manages content (posts, pages, custom post types, media). A separate frontend application fetches that content via GraphQL and renders it. WordPress becomes an API, not a website.
When headless WordPress makes sense
Good fit:
- Marketing sites with complex interactive components (configurators, calculators)
- Multi-channel content delivery (web, mobile app, digital signage)
- Teams with strong JavaScript/React skills but established WordPress content workflows
- Performance-critical sites where static generation or edge rendering matters
Poor fit:
- Content-heavy blogs that do not need interactivity beyond comments
- Sites relying heavily on WordPress plugins (WooCommerce, Gravity Forms, Elementor)
- Small teams that benefit from WordPress’s all-in-one approach
- Sites where editors need real-time preview with the actual frontend theme
Setting up WPGraphQL
Install the plugin
1 | # Via WP-CLI |
Once activated, WPGraphQL adds a /graphql endpoint to your WordPress installation and a GraphQL IDE at /wp-admin/admin.php?page=graphiql-ide.
Basic queries
1 | # Fetch recent posts |
1 | # Fetch a single post by slug |
Custom post types
1 | // functions.php — register a CPT with GraphQL support |
1 | # Query custom post type |
Custom fields with ACF
If you use Advanced Custom Fields, install the WPGraphQL for ACF extension:
1 | wp plugin install wpgraphql-acf --activate |
ACF field groups automatically appear in the GraphQL schema.
Frontend integration
Next.js (most common)
1 | // lib/wordpress.js |
1 | // app/page.tsx (Next.js App Router) |
Static site generation
For blogs and marketing sites, generate pages at build time:
1 | // app/blog/[slug]/page.tsx |
This fetches all post slugs at build time and pre-renders every page. Rebuilds happen on content change via a WordPress webhook.
Authentication and previews
Preview drafts
Editors need to preview unpublished content. This requires authentication:
1 | // WordPress: register a preview endpoint |
1 | // Next.js preview API route |
Common mistakes
Underestimating the plugin gap: WordPress plugins add frontend functionality (contact forms, SEO, comments, e-commerce). In headless mode, you rebuild all of that in your frontend. Budget for this.
Not handling WordPress HTML in content: The content field returns raw HTML from the WordPress editor. Your frontend needs to handle embedded images, iframes, Gutenberg block markup, and shortcodes.
1 | // You might need to process WordPress HTML |
Ignoring cache invalidation: When an editor publishes a post, your frontend cache needs to invalidate. Set up webhooks from WordPress to trigger rebuilds or cache purges.
Over-fetching with GraphQL: Request only the fields you need. Fetching full post content for a listing page wastes bandwidth.
Production tradeoffs
Hosting complexity: You now run two services (WordPress backend + frontend app) instead of one. This means two deployments, two sets of monitoring, and two potential points of failure.
Cost: WordPress hosting + Vercel/Netlify hosting + potentially a CDN. Compare against a single managed WordPress host.
Editor experience: Editors lose real-time preview with the actual theme. Content preview requires additional engineering. Some editors find this frustrating.
SEO: With static generation or server-side rendering, SEO is fine. With client-side rendering only, you risk SEO problems. Always use SSR or SSG for content pages.
FAQ
Can I use the REST API instead of GraphQL?
Yes. WordPress includes a REST API by default. It is simpler to set up but returns fixed response shapes. GraphQL is better when you need flexible queries or are fetching from multiple content types in a single request.
Is WooCommerce compatible with headless WordPress?
Partially. Product catalog and cart functionality work via the REST API or WooCommerce’s GraphQL extension. Checkout is complex and most teams keep it on WordPress or use a dedicated payment service.
Should I use WordPress.com or self-hosted for headless?
Self-hosted gives you full control over plugins and GraphQL extensions. WordPress.com restricts plugin installation, making WPGraphQL unavailable on lower tiers.
Next steps
Start by installing WPGraphQL on an existing WordPress site and exploring the GraphQL IDE. Query your existing content to see how it maps to the schema. Then build a minimal Next.js page that renders one post. The complexity grows from there, but the foundation is straightforward.
For building the GraphQL API layer, the GraphQL for PHP developers guide covers schema design and performance patterns. For understanding WordPress theme development, the existing WordPress theme guide provides the foundational knowledge of how WordPress structures content.