Using the WordPress REST API to Build a Headless Front‑End: Practical Guide
Learn how to expose WordPress content via the REST API, fetch it with JavaScript, secure CRUD operations using Application Passwords, and avoid common pitfalls. Verify your setup with simple checks and a minimal example.
07 Dec 2025, 07:44 UTC

Why Use the REST API?
The WordPress REST API exposes all core data—posts, pages, taxonomies, users—as JSON under /wp-json/wp/v2/. It is enabled by default in WordPress 4.7+, so you can immediately start building a JavaScript front‑end (React, Vue, Svelte, plain JS) that consumes the same content you manage in the CMS.
Getting Started: Enable and Test the Endpoint
1. Verify the endpoint is reachable:
Open https://your-site.com/wp-json/wp/v2/posts in a browser. You should see a JSON array with fields like id, title, content, and date.
2. Quick fetch test (any browser console):
fetch('https://your-site.com/wp-json/wp/v2/posts')
.then(r => r.json())
.then(console.log)
.catch(console.error);
Fetching Posts in a Headless App
Below is a minimal React component that pulls the latest 5 posts and displays the title and excerpt. Replace YOUR_SITE_URL with your domain.
import React, { useEffect, useState } from 'react';
const Posts = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('https://YOUR_SITE_URL/wp-json/wp/v2/posts?per_page=5')
.then(r => r.json())
.then(setPosts)
.catch(console.error);
}, []);
return (
{posts.map(p => (
{p.title.rendered}
))}
);
};
export default Posts;
Key points:
per_page=5limits the request to 5 items. The API capsper_pageat 100.- JSON fields are nested;
title.renderedandexcerpt.renderedcontain HTML. - For large datasets, use pagination headers (
X-WP-TotalandX-WP-TotalPages) to build navigation.
Securing CRUD Operations with Application Passwords
Anonymous requests can only read data. To create, update, or delete content, you need authentication. WordPress offers Application Passwords—simple Basic Auth tokens that can be generated per user.
- Log in to the WordPress admin, go to Users → Profile.
- Scroll to Application Passwords and give the new password a name (e.g., "Headless App").
- Copy the generated password; it will not be shown again.
- In your front‑end, include a Basic Auth header. Example with fetch:
const username = 'your-admin'; const appPassword = 'generated-application-password'; const headers = new Headers(); headers.append('Authorization', 'Basic ' + btoa(`${username}:${appPassword}`)); fetch('https://YOUR_SITE_URL/wp-json/wp/v2/posts', { method: 'POST', headers, body: JSON.stringify({ title: 'New Post from Headless App', content: 'Hello from the API!' }) }) .then(r => r.json()) .then(console.log) .catch(console.error); - Verify the request returns a 201 status and the new post appears in the admin panel.
Common Pitfalls and How to Avoid Them
- Missing Custom Fields: The REST API does not expose meta fields by default. Register them with
register_rest_fieldor use a plugin like ACF to REST API. - Pagination Overlook: Default
per_pageis 10. If you query more than that without setting the parameter, you’ll get incomplete data. Always checkX-WP-TotalPagesin the response headers. - Authentication Errors: 401/403 responses mean your credentials are wrong or missing. Double‑check the username, password, and that you’re using Basic Auth (no other schemes). Also, ensure the user has the
edit_postscapability. - CORS Restrictions: If you host the front‑end on a different domain, the server must send appropriate
Access-Control-Allow-Originheaders. WordPress handles this automatically for public endpoints, but for authenticated requests you may need a plugin or server‑side proxy.
Verifying Your Setup
1. Public data test:
Open https://YOUR_SITE_URL/wp-json/wp/v2/pages and confirm JSON output.
2. Authenticated request test:
Use the fetch snippet above with your Application Password and check for a 200/201 response. In the browser console, you should see the newly created post object.
3. Pagination check:
Send a request with per_page=200 and verify the response contains a 400 Bad Request or only 100 items, confirming the 100‑item cap.
4. Custom field test:
If you registered a meta field, query /wp-json/wp/v2/posts?fields=id,meta and ensure the meta object appears.
Conclusion
With the REST API, WordPress becomes a powerful headless CMS. By fetching data with JavaScript, securing write operations via Application Passwords, and being mindful of pagination and custom fields, you can build a fast, decoupled front‑end that still leverages WordPress’s content management strengths.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.