Headless WordPress Setup with Astro and React - Complete Guide
Mahesh Waghmare Headless WordPress separates content management from presentation, allowing you to use modern frontend frameworks like Astro and React while leveraging WordPress’s powerful CMS capabilities.
Introduction to Headless WordPress
Headless WordPress uses WordPress as a content API (head) while the frontend (body) is built with modern frameworks.
Benefits:
- Modern frontend frameworks
- Better performance
- Enhanced security
- Flexible deployment
- Improved developer experience
Architecture:
- WordPress backend (content management)
- REST API or GraphQL (data layer)
- Frontend framework (presentation)
WordPress Backend Setup
Enable REST API
WordPress REST API is enabled by default. Verify:
add_action('rest_api_init', function() {
// Custom endpoints can be added here
});
CORS Configuration
Allow frontend to access API:
add_action('rest_api_init', function() {
remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
add_filter('rest_pre_serve_request', function($value) {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Credentials: true');
return $value;
});
}, 15);
Custom Post Types
Register custom post types with REST API support:
register_post_type('project', [
'public' => true,
'show_in_rest' => true,
'rest_base' => 'projects',
'supports' => ['title', 'editor', 'thumbnail'],
]);
API Configuration
REST API Endpoints
Fetch Posts:
GET /wp-json/wp/v2/posts
Fetch Single Post:
GET /wp-json/wp/v2/posts/{id}
Fetch Pages:
GET /wp-json/wp/v2/pages
Custom Endpoints
add_action('rest_api_init', function() {
register_rest_route('my-plugin/v1', '/custom-data', [
'methods' => 'GET',
'callback' => 'get_custom_data',
'permission_callback' => '__return_true',
]);
});
function get_custom_data($request) {
return new WP_REST_Response([
'data' => 'value',
], 200);
}
Astro Frontend Integration
Install Dependencies
npm install axios
Create API Client
src/lib/wordpress-api.ts:
import axios from 'axios';
const API_URL = 'https://your-wordpress-site.com/wp-json/wp/v2';
export async function getPosts() {
const response = await axios.get(`${API_URL}/posts`);
return response.data;
}
export async function getPost(slug: string) {
const response = await axios.get(`${API_URL}/posts?slug=${slug}`);
return response.data[0];
}
export async function getPages() {
const response = await axios.get(`${API_URL}/pages`);
return response.data;
}
Fetch in Astro Pages
src/pages/blog/[…slug].astro:
---
import { getPost } from '../../lib/wordpress-api';
const { slug } = Astro.params;
const post = await getPost(slug);
---
<article>
<h1>{post.title.rendered}</h1>
<div set:html={post.content.rendered} />
</article>
React Components for WordPress
WordPress Post Component
import { useEffect, useState } from 'react';
export default function WordPressPost({ slug }: { slug: string }) {
const [post, setPost] = useState(null);
useEffect(() => {
fetch(`https://your-site.com/wp-json/wp/v2/posts?slug=${slug}`)
.then(res => res.json())
.then(data => setPost(data[0]));
}, [slug]);
if (!post) return <div>Loading...</div>;
return (
<article>
<h1 dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
<div dangerouslySetInnerHTML={{ __html: post.content.rendered }} />
</article>
);
}
Authentication and Security
Application Passwords
WordPress 5.6+ supports application passwords:
- Users → Profile → Application Passwords
- Create new password
- Use in Authorization header
API Authentication
const response = await fetch(`${API_URL}/posts`, {
headers: {
'Authorization': `Basic ${btoa('username:password')}`,
},
});
Rate Limiting
Implement rate limiting on WordPress side to protect API.
Deployment Strategy
Separate Deployments
- WordPress backend: Traditional hosting
- Astro frontend: Static site hosting (Cloudflare Pages, Vercel, Netlify)
Build Process
{
"scripts": {
"build": "astro build",
"preview": "astro preview"
}
}
Environment Variables
PUBLIC_WP_API_URL=https://your-wordpress-site.com/wp-json/wp/v2
Conclusion
Headless WordPress setup provides:
- Modern frontend development
- Better performance
- Flexible architecture
- Enhanced security
Key steps:
- Configure WordPress REST API
- Set up CORS
- Create API client in Astro
- Build frontend components
- Deploy separately
This architecture gives you the best of both worlds: WordPress’s powerful CMS and modern frontend frameworks.
Written by Mahesh Waghmare
I bridge the gap between WordPress architecture and modern React frontends. Currently building tools for the AI era.
Follow on Twitter →