WordPress

Building a headless WordPress site with WPGraphQL

WP

A media client loved WordPress's editorial experience but wanted a frontend that looked and behaved nothing like a typical WordPress theme, with more custom interactivity than templating WordPress's own rendering pipeline would comfortably support. We built the site headless, using the WPGraphQL plugin to expose WordPress content over a GraphQL API and a separate frontend application to consume it, keeping the editorial and presentation layers genuinely independent for the first time in this client's history with us.

Why a headless approach specifically, and not a heavily customized theme

We considered pushing further with a heavily customized traditional WordPress theme before recommending a headless approach, since a headless rebuild is a bigger architectural commitment than a theme customization project. What tipped the decision was the client's specific ambition for interactive, app-like features on the frontend — a live-updating comment stream, personalized content recommendations rendered client-side — that would have meant fighting against WordPress's server-rendered templating model at every turn rather than working with a tool built for exactly that kind of interactivity from the ground up.

Why this approach

  • The editorial team keeps the WordPress admin, Gutenberg blocks, and plugins they already know, with zero retraining needed on the content-creation side of their workflow, which mattered enormously to a client whose editorial staff had no appetite for learning an entirely new content management system on top of everything else changing
  • The frontend team builds and deploys completely independently, with no coupling to PHP templates at all, meaning a frontend deploy can happen mid-day without any coordination with WordPress's own release or plugin-update schedule
  • Custom post types and ACF fields map cleanly onto the GraphQL schema with very little extra configuration, since WPGraphQL's plugin ecosystem specifically targets this exact integration point rather than requiring us to hand-roll a custom API layer on top of WordPress ourselves

The tradeoffs

Some editorial WordPress plugins that render their own frontend markup do not translate to a headless setup, so we had to vet plugin choices more carefully than usual, since a plugin's marketing copy rarely mentions whether it depends on WordPress's own template rendering to function, and we only discovered a couple of incompatibilities through direct testing rather than any documentation warning us in advance.

Preview functionality for draft posts needed custom work to bridge WordPress's preview mechanism with the separate frontend, since WordPress's built-in preview feature assumes it is previewing its own theme's rendering, not a completely separate frontend application running on different infrastructure. We built a small preview token system that lets the separate frontend fetch a specific draft's content directly, bypassing the published-content-only default that WPGraphQL ships with, specifically to give editors the same confident "see it before you publish it" workflow they were used to.

The client now runs two deployable things instead of one, which is a real increase in operational surface area — two things that can each independently break, each with their own deploy pipeline, their own monitoring, and their own on-call considerations, none of which existed as separate concerns under the client's previous single-theme setup.

How we handled the increase in operational complexity

We standardized both the WordPress backend and the frontend application onto the same monitoring and alerting setup we already use for other clients, specifically to avoid the headless architecture's added complexity translating into genuinely worse operational visibility than the simpler setup it replaced. A single combined status dashboard, showing both systems' health at a glance, has been enough to keep the added complexity from becoming a genuine burden on the small internal team that eventually inherits day-to-day operation of this site from us.

Results and where this pattern fits

For a client whose frontend ambitions have genuinely outgrown what a WordPress theme can comfortably deliver, but whose editorial workflow depends on WordPress, this pattern is a good middle ground. We would not recommend it for a client without that specific combination of needs — a straightforward brochure or blog site gains nothing from the added complexity of a separate frontend application, and the operational cost described above is a real cost that only makes sense to take on when the frontend ambitions genuinely justify it.

Handling authentication across two separate systems

A user commenting on an article, or a logged-in subscriber accessing premium content, now needs to authenticate against a system that spans both the WordPress backend and the separate frontend application, rather than relying on WordPress's own built-in session and cookie handling the way a traditional theme would. We implemented a token-based authentication layer issued by WordPress and validated independently by the frontend on every request, which took real design work to get right — particularly around token expiration and refresh — but avoids tightly coupling the frontend's session handling to WordPress-specific cookie behavior that would have made the two systems harder to evolve independently.

SEO considerations that needed extra attention

A completely custom frontend loses WordPress's own built-in SEO plugin ecosystem's automatic handling of meta tags, structured data, and sitemaps, since those plugins generate their output as part of WordPress's own template rendering, which the headless frontend never touches. We had to rebuild equivalent SEO metadata generation directly in the frontend application, pulling the relevant fields — meta description, Open Graph tags, canonical URLs — through the GraphQL API from the same SEO plugin's underlying data, which the plugin fortunately did expose through its own WPGraphQL extension, saving us from having to build that data layer entirely from scratch ourselves.

How editorial workflow changed in ways nobody anticipated upfront

One unplanned but welcome side effect: with the frontend team building against a stable, well-documented GraphQL schema rather than directly coupled to WordPress template quirks, editorial staff started requesting new custom fields and content types more freely, since a new field showing up cleanly in the GraphQL schema and then appearing on the frontend became a noticeably faster, lower-friction cycle than the old process of a developer needing to also update PHP template files by hand for every new content structure the editorial team wanted to introduce.

What we would scope differently on a similar project next time

Knowing what we know now, we would budget real time specifically for the authentication and SEO metadata work described above from the very start of project scoping, rather than treating them as smaller follow-on tasks after the main content-fetching integration was working, since both ended up consuming more of the project's total timeline than our original, more optimistic estimate anticipated.

← Back to the journal

Have a project in mind?
Let’s talk.

Tell us where you are and where you want to go. We'll map the fastest route between the two.

Currently accepting new clients