Complete Guide to Building a Headless WordPress CMS

作者:

在

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 _embed param embeds featured image, author, and category in one response, saving extra requests.
  • revalidate enables 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

  1. Backend: Deploy WordPress on a server with PHP; add Redis object caching.
  2. Frontend: Deploy Next.js to Vercel/Cloudflare Pages; static assets go through a CDN.
  3. Caching: Add Cache-Control to REST responses and pair with CDN edge caching.
  4. 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_head or 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.

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注