Migrating a Legacy PHP Site to Headless WordPress with React

A client had a 10-year-old custom PHP site — spaghetti code, no CMS, content hardcoded in templates. They wanted a modern site they could actually update themselves. The solution: WordPress as a headless CMS with a React frontend.
Why Headless?
The client needed a fast, modern frontend but also wanted the familiarity of WordPress for content management. Headless gives you both: WordPress handles content, media, and user management while React delivers a snappy, app-like experience to visitors.
Setting Up the WordPress Backend
I set up WordPress with custom post types for each content type the old site had — services, team members, case studies. The REST API exposes all of this automatically when you set show_in_rest to true:
register_post_type("service", [
"public" => true,
"show_in_rest" => true,
"supports" => ["title", "editor", "thumbnail", "excerpt"],
"has_archive" => false,
]);
For custom fields, I used register_post_meta with show_in_rest so every field is available via the API without any extra endpoints.
The React Frontend
The frontend uses React with React Router for client-side navigation. Data fetching is straightforward — just fetch calls to the WordPress REST API:
const API_BASE = "https://cms.example.com/wp-json";
export async function getServices() {
const res = await fetch(`${API_BASE}/wp/v2/service?_embed`);
return res.json();
}
The _embed parameter is crucial — it includes featured images and taxonomy data in a single request instead of requiring separate API calls.
The Biggest Pitfall: SEO
Single-page apps and SEO have historically been enemies. For this project, I used server-side rendering to ensure search engines could crawl the content. The React frontend pre-renders each page on the server, so crawlers get fully-formed HTML.
The Result
The new site loads in under a second, the client manages content through WordPress, and the codebase is actually maintainable. The migration took about three weeks, but the old site would have needed a complete rewrite regardless.
Written by
Adrian Saycon
A developer with a passion for emerging technologies, Adrian Saycon focuses on transforming the latest tech trends into great, functional products.
Discussion (0)
Sign in to join the discussion
No comments yet. Be the first to share your thoughts.
Related Articles

Building and Deploying Full-Stack Apps with AI Assistance
A weekend project walkthrough: building a full-stack task manager from architecture planning to deployment, with AI as t

AI-Assisted Database Design and Query Optimization
How to use AI for schema design, index recommendations, N+1 detection, and query optimization in PostgreSQL and MySQL.

How MCP Servers Are Changing AI-Assisted Development
An introduction to Model Context Protocol (MCP) and how to set up and build MCP servers that connect AI tools to your de