Astro.jsとWP REST APIを使ったブログの作成
準備
初期セットアップは前回と一緒なので割愛
今回はこのブログのWP REST APIを使用します。 とりあえず、使うエンドポイントは2つ
https://cms.codecodeweb.com/wp-json/wp/v2/posts?_embed&per_page=10
https://cms.codecodeweb.com/wp-json/wp/v2/posts/【記事ID】
記事一覧
/src/pages/index.astro
を編集します。
まずは記事データをfetchします。
index.astro
---
const res = await fetch("https://cms.codecodeweb.com/wp-json/wp/v2/posts?_embed&per_page=10")
const posts = await res.json()
---
index.astro
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CodeCode</title>
</head>
<body>
<h1>CodeCode</h1>
{
posts.map((post) => (
<h2>
<a href={`/posts/${post.id}/`} set:html={post.title.rendered} />
</h2>
<p set:html={post.excerpt.rendered} />
))
}
</body>
</html>
取得した記事をmapで回して一覧を出力します。
今回はリンクに記事のIDを使用します。
記事詳細
Dynamic routesを使って各ページを生成します。
今回の詳細ページは一覧で作ったリンクのように /posts/【記事のID】
、/posts/1
、/posts/2
のようになります。
Dynamic routesはこの記事IDのように動的に変化するページを生成してくれます。
/src/pages/
にposts
ディレクトリを作り、そこに[id].astro
を作ります。
ファイル名の[id]
が記事IDに応じて動的に変わっていきます。
[id].astro
---
export async function getStaticPaths() {
// 最大数(全記事)の記事を取得
// wp-rest-apiの取得上限が100なのでとりあえず最大値
let data = await fetch("https://cms.codecodeweb.com/wp-json/wp/v2/posts?_embed&page=1&per_page=100")
let posts = await data.json();
return posts.map((post) => ({
params: { id: post.id },
props: { post: post },
}));
}
---
Dynamic routesを使用する際は、getStaticPaths関数が必要です。
getStaticPathsを元に反復的にページが生成されます。
なので、ここでは全記事を取得するためwp-rest-apiの取得上限値の100を設定します。
100件以上取得するときはWordPress側で設定が必要です。
また、ページの最大数はheaderにあるので、
let data = await fetch(`https://cms.codecodeweb.com/wp-json/wp/v2/posts`)
let total = await data.headers.get('X-WP-Total')
で取得できるのでtotalを使ってもう一度記事をfetchする方法もあります。
各記事のIDと記事の内容を配列として返却します。
その続きに各ページの詳細を個別に取得します。
const { id } = Astro.params;
でパラメーターであるIDが取得できるので、https://cms.codecodeweb.com/wp-json/wp/v2/posts/【記事ID】
をfetchします。
const { id } = Astro.params;
let res = await fetch(`https://cms.codecodeweb.com/wp-json/wp/v2/posts/${id}`)
let post = await res.json();
個別に取得したデータを出力します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CodeCode</title>
</head>
<body>
<h1>CodeCode</h1>
<article>
<h1 set:html={post.title.rendered} />
<Fragment set:html={post.content.rendered} />
</article>
</body>
</html>
Build
npm run build
するとdistにHTMLが出力されます。
postsの中には記事IDのディレクトリができて、記事のHTMLが出力されています。
dist
├── favicon.svg
├── index.html
└── posts
├── 110
│ └── index.html
├── 123
│ └── index.html
├── 162
│ └── index.html
├── 199
│ └── index.html
~中略~
└── 98
└── index.html