MADEBYARIS

Headless WordPress with Next.js: how I wire the front

4 min read
By Aris Setiawan
Headless WordPress with Next.js: how I wire the front

I use WordPress as the CMS. Next.js is the site. That is the split.

The visitor hits Next.js. WordPress stores the post. I do not treat WP as the public page.

I’m Aris Setiawan. I ship this on client work and on madebyaris.com. This site is Next.js on the front. The CMS is wp.madebyaris.com. I already wrote when headless WordPress is worth it. That post is the why. This one is the practice: how I wire a headless WordPress Next.js front in App Router.

The hire doors are headless WordPress development and Hire a Next.js developer. This is the wiring, not a sales page.

WP stays the CMS

WordPress holds posts, drafts, media, and the editor the client already knows. That is the job. I do not ask it to paint the public HTML.

A theme is not the site. A page builder is not the site. If a plugin is “the front,” I am not doing headless. I am running two sites and hoping they agree.

On madebyaris.com I write in wp.madebyaris.com. Status, slug, featured image, Gutenberg blocks. The public URL is a Next.js route. WP never sees that request.

CMS vs the front

Next.js owns the request

App Router. A folder is a URL. page.tsx is a Server Component. It fetches. It tags the result. The visitor never waits on a PHP theme.

I already wrote the App Router I keep in `app/`. The headless case does not invent a new tree. Same layout, same small client boundary, same cache I can walk after a write.

If the request lands on WordPress and Next.js “pretty-prints” it later, that is not the split. Next.js owns the request from the first byte.

How I fetch

REST. GET /wp-json/wp/v2/posts?slug=.... I ask for the fields I use: title, slug, content, excerpt, featured image, status. I do not pull the whole kitchen.

I fetch in the Server Component. I pass next: { tags: ['posts', 'post:' + slug] }. Public list can cache. A cookie or a draft cannot.

How I fetch: visitor, page, REST, CMS

I do not open a GraphQL layer unless the product already has one I can name. A mystery GraphQL stack on top of REST I already trust is a second contract I have to debug at 1am.

Preview uses a secret. The public list does not. If I mix those two fetches, a draft leaks or a public page goes no-store for no reason.

Draft and preview

Draft stays in WordPress. I do not flip a post to publish so I can “see it.”

Preview is a Next.js route. It reads the draft with an application password or a preview nonce. no-store. If I cache a draft, the next editor sees yesterday’s sentence.

The public slug route 404s a draft. That is the point. Status is the gate. The front does not invent a second status field.

What I revalidate after a publish

I name the tags before I write the hook.

posts for the blog index. post:{slug} for the single URL. home only if the homepage lists posts.

Publish, then bust the named cache

A publish hook hits a Next.js route. It checks a secret. It calls revalidateTag or revalidatePath. Then the next visitor gets the new HTML.

If I cannot name the tag, the edit sits invisible until someone redeploys. I have already sat in that chair. I will not ship it again.

I do not bust the whole site because one post changed. That is how you turn a publish into a stampede.

What I skip

Rewriting when headless is worth it. That page already owns the why.

Treating WordPress as the site and Next.js as a pretty cache.

A GraphQL schema I cannot walk in one sitting.

Caching a draft so preview “feels fast.”

A weekend “headless rewrite” with no owner for the front. Same failure as a Pages-to-App-Router big bang.

What I will take

I will take a WordPress site that needs a Next.js front, or a Next.js front that still treats WP as the HTML. Fetch, draft, preview, a tag I can bust after publish. I will not take a rewrite that leaves two publics live and hopes they stay in sync.

If you want that owned, that is headless WordPress development or Hire a Next.js developer. Send the CMS URL and the front repo.

Tags:

Aris Setiawan

Aris Setiawan

Senior Full Stack Developer specializing in Next.js, React, and WordPress. I write about web development, performance optimization, and best practices.

Related Articles