Headless CMS for a Brand Site

A company brand site serves two groups with different needs. The marketing team wants to publish and update content without waiting for a developer. Visitors want pages that load fast, look consistent, and never break. A traditional WordPress theme serves the first group well and often struggles with the second. A headless setup splits the job: WordPress manages the content, and a Next.js frontend delivers it.

This note describes the setup I run for our brand site, why I chose it, and where it costs more than it gives back. Headless is not always the better choice, and I want to be fair to both sides.

6 min read

The Stack at a Glance

  • Server management: RunCloud handles the web server, SSL, domains, and the PHP environment on our own VPS.
  • CMS: WordPress, served under /cms/. Editors use it to create and manage posts and pages, and that is all it does.
  • Frontend: Next.js, living in /frontend/, running on Node.js inside a Docker container.
  • Process supervision: Supervisor keeps the frontend container running, restarts it when it fails, and brings it back after a server reboot.
  • Connector plugin: a custom WordPress plugin that handles communication between WordPress and Next.js, including revalidation.
  • Release tooling: release, deploy, and rollback scripts, so every frontend change is repeatable and reversible.

How the Pieces Connect

WordPress as a content source
I keep WordPress to a single job.

  • Editors log in at /cms/, write posts, upload media, and publish. They already know the editor, so the team needed almost no training.
  • Visitors never see a WordPress theme. The theme layer is minimal, and public traffic never reaches WordPress templates.
  • Content is exposed through the REST API, shaped by the connector plugin so the frontend gets exactly the fields it needs.

The connector plugin
This is the glue between the two systems, and most of the custom logic lives here.

  • It registers custom endpoints or fields, so the frontend gets clean, predictable data instead of raw WordPress output.
  • It listens for content events such as publish, update, unpublish, and delete.
  • It calls a revalidation endpoint on Next.js with a shared secret, telling it which paths or tags are now stale.
  • It lets editors preview drafts on the real frontend before they go live.

Next.js as the delivery layer
Next.js renders everything a visitor sees.

  • Pages are statically generated or cached, so most requests are served without touching WordPress.
  • An API route checks the secret from the connector plugin, then revalidates only the affected pages.
  • Design, components, and performance are controlled in code, which keeps the brand consistent on every page.

Docker and Supervisor on RunCloud
RunCloud does not manage Node.js apps the way it manages PHP apps, so I fill that gap myself.

  • The Next.js app runs in a Docker container, which pins the Node.js version and keeps the runtime identical between builds.
  • Supervisor owns the container process. If it crashes, Supervisor restarts it, and after a reboot it comes back on its own.
  • The web server proxies public traffic to the container, while PHP keeps serving /cms/ as usual.

Publishing Flow

  1. Editor publishes or updates a post in /cms/
  2. Connector plugin catches the save event
  3. Plugin calls the Next.js revalidate endpoint with a secret
  4. Next.js verifies the secret, refreshes only the affected pages
  5. Visitors get the updated page, served from cache

Editors don’t need to know any of this. They click publish, and within seconds the live site shows the change, with no full rebuild and no deployment.

Release, Deploy, and Rollback

Content changes go out through revalidation, and code changes go out through scripts. Keeping those two paths separate is one of the main benefits of this setup.

Release
The release script builds the frontend into a new, versioned release directory. Each release is self-contained, so building a new version never touches the one serving traffic.

Deploy
The deploy script points the active release at the new build and restarts the process through Supervisor. The switch is quick, and if the build failed, the current version keeps running.

Rollback
Previous releases stay on the server. Rolling back means pointing at the last known good release and restarting: one command, no rebuild. I decided how to roll back before any incident happened, which is the principle from A Practical Deployment Pipeline.

Cleanup
Only a limited number of old releases are kept, so disk usage stays predictable and there is still enough history to roll back safely.

Advantages

  • Performance: cached and statically generated pages are fast by default, which helps both the user experience and Core Web Vitals.
  • Security: the public never talks to WordPress templates or plugins directly, which shrinks the attack surface a lot. The /cms/ area can be locked down further.
  • Brand consistency: layout and design live in code and components, so editors cannot accidentally break the look of the site.
  • Familiar editing: the marketing team keeps the WordPress editor they already know.
  • Independent release cycles: a frontend deploy never blocks publishing, and publishing never needs a deploy.
  • Safe deployments: with versioned releases and one-command rollback, a bad deploy is a short inconvenience instead of an outage.
  • Portability: the frontend could later read from a different CMS, or WordPress could feed other channels, without rebuilding everything.

Disadvantages

  • Two systems to maintain: WordPress core, plugins, and PHP on one side; Node.js, Next.js, and Docker on the other. Both need updates and monitoring.
  • Custom glue code: the connector plugin is ours. When WordPress or Next.js changes behavior, keeping it working is our problem.
  • Lost WordPress conveniences: many plugins assume a WordPress theme renders the page. Page builders, form plugins, and some SEO features either stop working or have to be rebuilt on the frontend.
  • Harder previews: draft previews take extra work to feel as natural as they do in a classic theme.
  • Revalidation edge cases: if a revalidation call fails or misses a related page, such as a listing or category page, visitors may see stale content until the next refresh.
  • More operational knowledge: RunCloud simplifies the PHP side, but someone has to understand Docker, Supervisor, and the release scripts.
  • Higher initial cost: the first build takes noticeably longer than installing a theme and going live.

When It Makes Sense

Situation Headless Traditional WordPress
Performance and brand control matter Strong fit Possible, with effort
Editors rely on page builders Poor fit Strong fit
A developer maintains the site Strong fit Strong fit
No technical owner available Risky Safer
Frequent code changes and releases Strong fit Harder to manage safely

For our brand site the trade was worth it. We have a technical owner, the design has to stay tightly controlled, and the content is mostly posts and pages rather than complex page building.

Lessons from Running It

Keep WordPress boring
Install only the plugins that support content editing. Every extra plugin is one more thing to update, and it may not even make sense in a headless setup.

Treat the connector plugin as a product
Version it, document its endpoints, and log its revalidation calls. When content looks stale, those logs are the first place to look.

Revalidate relationships as well as pages
A new post affects more than its own URL. Home page sections, listing pages, and category pages usually need to refresh too.

Test rollback before you need it
A rollback script that has never run is only a hope. Run it on a quiet day so it is familiar when it matters.

Monitor both sides
Uptime checks on the public site, error tracking in Next.js, and basic health checks on /cms/ surface problems before visitors or editors report them.

A headless setup is more work than a classic WordPress site, and I would not recommend it to every company. When the brand, performance, and release safety matter and someone owns the technical side, editors keep a tool they know and visitors get a faster, more reliable site.

Next step

Have a project in mind? Let's talk.

Tell me what you have and what you need. I'll usually reply within one working day with how I'd approach it.