WordPress REST APIをJavaScriptから操作する方法
WordPress REST APIをJavaScriptから操作する方法
WordPressの投稿データをフロントエンドのJavaScriptから取得したり更新したりしたいケースは多い。WordPressのREST APIはデフォルトで有効になっており、fetchAPIを使えば簡単に操作できる。認証が必要な操作と不要な操作の違いも含めて解説する。
WordPress REST APIの基本
ベースURLは以下の形式:
https://example.com/wp-json/wp/v2/
代表的なエンドポイント:
| エンドポイント | 説明 |
|—————|——|
| /wp/v2/posts | 投稿の取得・作成 |
| /wp/v2/posts/{id} | 特定投稿の取得・更新・削除 |
| /wp/v2/categories | カテゴリ一覧 |
| /wp/v2/tags | タグ一覧 |
| /wp/v2/media | メディア(画像等) |
| /wp/v2/users | ユーザー情報 |
認証なしで取得できる情報
公開されている投稿や固定ページは認証なしで取得できる。
// 最新10件の投稿を取得
async function getLatestPosts(siteUrl, count = 10) {
const url = `${siteUrl}/wp-json/wp/v2/posts?per_page=${count}&_embed`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const posts = await response.json();
return posts;
}
// 使用例
const posts = await getLatestPosts('https://example.com');
posts.forEach(post => {
console.log(`${post.title.rendered}: ${post.link}`);
});
_embedパラメータを付けると、アイキャッチ画像などの関連データを一緒に取得できる。
カテゴリを指定して投稿を絞り込む
async function getPostsByCategory(siteUrl, categoryId, page = 1) {
const params = new URLSearchParams({
categories: categoryId,
per_page: 10,
page: page,
_embed: true,
orderby: 'date',
order: 'desc'
});
const response = await fetch(`${siteUrl}/wp-json/wp/v2/posts?${params}`);
// ヘッダーからページング情報を取得
const totalPosts = response.headers.get('X-WP-Total');
const totalPages = response.headers.get('X-WP-TotalPages');
const posts = await response.json();
return {
posts,
totalPosts: parseInt(totalPosts),
totalPages: parseInt(totalPages),
currentPage: page
};
}
REST APIのレスポンスヘッダーにはX-WP-Total(総件数)とX-WP-TotalPages(総ページ数)が含まれる。ページネーションに使える。
Application Passwordsによる認証
投稿の作成・更新・削除には認証が必要。WordPress 5.6以降はApplication Passwordsが標準機能として使える。
WordPress管理画面 → ユーザー → プロフィール → アプリケーションパスワードで発行する。
class WordPressClient {
constructor(siteUrl, username, appPassword) {
this.siteUrl = siteUrl;
// Basic認証のトークンを作成
this.authToken = btoa(`${username}:${appPassword}`);
}
getHeaders(includeAuth = false) {
const headers = {
'Content-Type': 'application/json',
};
if (includeAuth) {
headers['Authorization'] = `Basic ${this.authToken}`;
}
return headers;
}
// 認証なし: 公開投稿の取得
async getPosts(params = {}) {
const query = new URLSearchParams({ per_page: 10, ...params });
const response = await fetch(
`${this.siteUrl}/wp-json/wp/v2/posts?${query}`,
{ headers: this.getHeaders(false) }
);
if (!response.ok) throw new Error(`Error: ${response.status}`);
return response.json();
}
// 認証あり: 投稿の作成
async createPost(postData) {
const response = await fetch(
`${this.siteUrl}/wp-json/wp/v2/posts`,
{
method: 'POST',
headers: this.getHeaders(true),
body: JSON.stringify(postData)
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return response.json();
}
// 認証あり: 投稿の更新
async updatePost(postId, postData) {
const response = await fetch(
`${this.siteUrl}/wp-json/wp/v2/posts/${postId}`,
{
method: 'POST', // PATCHでもPOSTでもどちらでも更新できる
headers: this.getHeaders(true),
body: JSON.stringify(postData)
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return response.json();
}
}
投稿を作成する
const client = new WordPressClient(
'https://example.com',
'username',
'xxxx xxxx xxxx xxxx' // Application Password(スペースは含めて問題ない)
);
// 下書きとして投稿を作成
const newPost = await client.createPost({
title: '新しい記事タイトル',
content: '記事の本文です。
',
status: 'draft', // 'publish'で公開、'draft'で下書き
categories: [12, 15], // カテゴリIDの配列
tags: [3, 7], // タグIDの配列
excerpt: 'この記事の概要です。'
});
console.log(`投稿作成完了: ID ${newPost.id}, URL: ${newPost.link}`);
カテゴリIDを名前から検索する
カテゴリIDは直接わからないので、名前から検索する:
async function getCategoryIdByName(siteUrl, categoryName) {
const params = new URLSearchParams({ search: categoryName, per_page: 10 });
const response = await fetch(`${siteUrl}/wp-json/wp/v2/categories?${params}`);
const categories = await response.json();
// 完全一致するカテゴリを探す
const match = categories.find(cat => cat.name === categoryName);
return match ? match.id : null;
}
// 使用例
const pythonCategoryId = await getCategoryIdByName('https://example.com', 'Python');
エラーハンドリング
async function safeApiCall(apiFunction, ...args) {
try {
return await apiFunction(...args);
} catch (error) {
if (error.message.includes('401')) {
console.error('認証エラー: Application Passwordを確認してください');
} else if (error.message.includes('403')) {
console.error('権限エラー: このユーザーには権限がありません');
} else if (error.message.includes('404')) {
console.error('見つかりません: エンドポイントまたはリソースが存在しないか確認してください');
} else {
console.error('APIエラー:', error.message);
}
throw error;
}
}
CORSに注意
ブラウザのJavaScriptから別ドメインのWordPressに直接アクセスするとCORSエラーが出ることがある。
WordPressのCORSを許可する設定(functions.phpに追加):
add_action('init', function() {
header("Access-Control-Allow-Origin: https://your-frontend-domain.com");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Authorization, Content-Type");
});
本番環境では*(全ドメイン許可)ではなく、フロントエンドのドメインを明示的に指定すること。
まとめ
JavaScript(fetch API)でWordPress REST APIを操作するポイント:
WordPressをヘッドレスCMSとして使ったり、管理ツールをSPAで作ったりする際の参考にしてほしい。