Traditional WordPress is “front-and-back in one”: theme templates mix HTML, PHP, and query logic. A “headless CMS” splits it in two—using WordPress only for content on the backend, and any tech stack for frontend rendering. This is a complete guide to building a headless WordPress CMS from scratch, covering architecture, APIs, auth, and deployment.
1. Why Go Headless with WordPress?
Three typical scenarios suit headless transformation:
- Frontend/backend team separation: Backend uses WordPress for content, frontend built with React/Vue.
- Multi-end reuse: The same data must serve a website, app, and mini-program.
- Performance and SEO: Frontend uses SSG static generation for better first-screen and SEO.
2. Overall Architecture
A minimal headless WordPress architecture:
┌────────────┐ REST/GraphQL ┌────────────┐
│ WordPress │ ←─────────────────→ │ Frontend │
│ (content) │ │ (Next/Nuxt)│
└────────────┘ └────────────┘
│ │
│ │
MySQL/MariaDB Static hosting
(Vercel/CDN)
The backend handles content storage and API output; the frontend handles rendering and interaction.
3. Backend Config: Enable REST and Custom Fields
WordPress ships with a REST API; the default path is /wp-json/wp/v2/posts. But bare REST fields aren’t enough, so it’s usually paired with two plugins:
- ACF (Advanced Custom Fields): Adds custom fields to posts.
- WPGraphQL or ACF to REST API: Exposes custom fields through the API.
A code example for registering a custom post type:
// Register a "project" custom post type
function register_project_cpt() {
register_post_type('project', [
'label' => 'Project',
'public' => true,
'show_in_rest' => true, // Key: expose to REST
'rest_base' => 'projects',
'supports' => ['title','editor','excerpt','thumbnail','custom-fields'],
]);
}
add_action('init', 'register_project_cpt');
show_in_rest => true is the key to making a custom type appear in the REST API.
4. Auth: Application Passwords vs JWT
Reading public content needs no auth, but writing or reading drafts does. Two mainstream options:
| Option | Implementation | Use case |
|---|---|---|
| Application password | Generated in admin, Basic Auth | Server-to-server |
| JWT plugin | Login for token, request with Authorization | Frontend login scenarios |
Application passwords are simplest: generate one in WordPress admin under “Users – Application Passwords,” then the frontend request includes Authorization: Basic base64(user:pass).
5. Frontend Fetching and Static Generation
Using Next.js as an example, fetch a post list and statically generate:
export async function getStaticProps() {
const res = await fetch(`${process.env.WP_API}/posts?_embed&per_page=10`);
const posts = await res.json();
return {
props: { posts },
revalidate: 60, // ISR incremental static regeneration
};
}
Key points:
- The
_embedparam embeds featured image, author, and category in one response, saving extra requests. revalidateenables ISR, auto-regenerating static pages after content updates.- Draft preview requires a preview route that swaps an application password for a token.
6. Deployment and Caching
- Backend: Deploy WordPress on a server with PHP; add Redis object caching.
- Frontend: Deploy Next.js to Vercel/Cloudflare Pages; static assets go through a CDN.
- Caching: Add
Cache-Controlto REST responses and pair with CDN edge caching. - Update trigger: When WordPress publishes a post, call a webhook to notify the frontend to rebuild.
7. Three Common Pitfalls
- ACF fields not returned: Remember to check “Show in REST API” in the field group settings.
- Media URL cross-origin: When image and frontend domains differ, configure CORS headers via
wp_heador use a proxy. - Chinese slug encoding: Use %post_id%.html for permalinks instead of %postname% to avoid Chinese URL issues.
8. Summary
The essence of headless WordPress is “WordPress as backend, a modern framework as frontend.” Its value isn’t “banishing themes” but letting content serve multiple ends, letting the frontend use a modern toolchain, and benefiting both first-screen and SEO. If you already have WordPress content and want a modern frontend experience, going headless is the highest-ROI path. Start from a minimum viable architecture and gradually add caching, preview, and incremental builds to get a content system that’s both familiar and modern.

发表回复