[Astro] Ghost CMS で作るブログ
Ghost(CMS)で投稿した記事を Astro製のブログで表示する方法です。
前提
- Ghost でアカウント作成済み
- Ghost で記事を投稿済み
導入方法
1. Ghost 側でサイトを非表示にする
Ghost にはヘッドレスCMSとしての使用を前提とした設定があるため有効にする。
管理画面 > Settings > General > Make site private へ移動し [Edit] をクリック。
Enable password protection
をonにする。
以下が Ghost 側のブログに適用される。
- Ghost側のフロントエンドにパスワードが設定される
- SEO機能が無効になる
-
noindex
タグが付与される
2. Ghost APIキーを作成する
管理画面 > Settings > Advanced > Integrations へ移動し、[Add Custom integration] からTitleを入力して保存する。
Content API key (read-only), Admin API key, API URLが表示されたら作成完了。
3. Astro のインストール
npm create astro@latest
画面に従って選択していく
インストール完了後、以下を実行して画面が表示されるのを確認する。
npm run dev
4. Ghost の投稿データ取得のためのセットアップ
.env
ファイルに 手順2. で作成したAPIキーを入力する。
CONTENT_API_KEY=<YOUR_CONTENT_API_KEY>
src/env.d.ts
ファイルに以下を追記する。
interface ImportMetaEnv {
readonly CONTENT_API_KEY: string;
}
Ghost のAPIを利用するためのパッケージをインストールする。
npm install @tryghost/content-api
npm install --save @types/tryghost__content-api
Ghost APIのインスタンスを作成する
import GhostContentAPI from "@tryghost/content-api";
export const ghostClient = new GhostContentAPI({
url: "http://<YOURDOMAIN>.ghost.io", // Ghostで作成したアカウントのドメインを入力
key: import.meta.env.CONTENT_API_KEY,
version: "v5.0",
});
5. 記事一覧を作成する
pages 配下の index.astro で記事一覧を表示します。
ここでは以下の条件で取得・表示する例です。
- 最新8件
- Ghost側で公開済みとなっている
※ ここでは省略しますが、日付はフォーマットが必要です。
---
...
import { ghostClient } from "../lib/ghost.ts";
const posts = await ghostClient.posts
.browse({
filter: "visibility:public",
limit: 6,
})
.catch((err) => {
console.error(err);
});
---
<Layout>
<main>
{
posts.map(
(post) => (
<a href={`/posts/${post.slug}`} title={post.title} class="post_link">
<article class="">
<div class="post_image">
<img src={post.feature_image} alt={post.feature_image_alt} />
</div>
<div class="post_text">
<div>
<div class="post_date">
<time datetime={post.published_at}>{post.published_at}</time>
</div>
<p class="post_title">{post.title}</p>
</div>
<p class="post_excerpt">{post.excerpt}</p>
</div>
</article>
</a>
)
)
}
</main>
</Layout>
6. 記事詳細を作成する
記事のURLを /posts/post-slug/ とする場合、 src/posts/[slug].astro を作成します。
getStaticPaths()
で記事データを取得して、 slug
を Astro の params に記事URLとして設定します。
記事本文はAPIで html として渡されるので、
---
import type { PostsOrPages, PostOrPage } from "@tryghost/content-api";
import { ghostClient } from "../lib/ghost.ts";
export async function getStaticPaths() {
const posts: PostsOrPages = await ghostClient.posts
.browse({
filter: "visibility:public",
limit: "all",
})
.catch((err) => {
console.error(err);
});
if (!posts) {
throw new Error("Opps, something wrong");
}
return posts.map((post: PostOrPage) => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
---
<article>
<h1>{post.title}</h1>
<p>{post.published_at}</p>
<img src={post.feature_image} alt={post.title} />
<Fragment set:html={post.html} />
</article>
参考
Astro 公式 Ghost 導入ガイド
Ghost をヘッドレスCMSとして利用する
Discussion