BLOG
AstroのContent Collectionsでブログをつくる
INDEX
Content Collectionsは.md
や.mdx
を型安全に管理するためのAstroの機能です。[email protected]で追加されました。
投稿日やタイトルなど、各ファイルで使用するデータに型を定義をすることで、型が間違っていたら実行時やビルド時にエラーが出て安全、というわけです。
ここではContent Collectionsを用いた簡単なブログの構築手順をご紹介します。
インストール
npm create astro@latest
以下項目を尋ねられるので選択はお好みで。
How would you like to start your new project?
Where should we create your new project? // プロジェクトのディレクトリ
How would you like to start your new project? // テンプレートの有無
● Include sample files (recommended) // サンプルファイルを含める(推奨)
○ Use blog template // ブログテンプレートを使う
○ Empty // 空
Install dependencies? (recommended) // 依存関係のインストールの有無(推奨)
● Yes ○ No
Do you plan to write TypeScript? // TypeScriptを書くか
● Yes ○ No
use How strict should TypeScript be? // TypeScriptの厳格さ
● Strict (recommended) // 厳格(推奨)
○ Strictest // もっとも厳しい
○ Relaxed // リラックス
git Initialize a new git repository? (optional) // gitリポジトリの初期化の有無
● Yes ○ No
How would you like to start your new project?
にてUse blog template
を選択することでもブログの構築が可能です。
インストールが終わったら、cdコマンドで作ったディレクトリに移動して以下コマンドを入力するとローカルサーバーが起動します。
npm run dev
コンテンツを格納するディレクトリをつくる
Content Collectionsではコンテンツを管理するためにsrc/content
ディレクトリを使用します。
なおsrc/content
ディレクトリは予約されているので、Content Collections以外の用途で使用することはできず。
src
ディレクトリの中にcontent
ディレクトリをつくり、この中に管理したいコンテンツのコレクション名を命名したディレクトリをつくります。
ここではblog
1つですが、コレクションはいくらでも追加できます。
src
└ content
└ blog
コレクションのディレクトリを追加後、ローカルサーバーを立て直すとルートに.astro
ディレクトリが自動で追加されます。
.astro
ディレクトリにはContent Collectionsのためのメタデータが格納されます。
このディレクトリにまつわる心配はご無用で、実行時やビルド時にAstroが自動で更新してくれます。
.gitignore
に追加しても問題ありません。
echo "\n.astro" >> .gitignore
コレクションを定義する
ディレクトリをつくったら今度は設定です。
コレクションがどのようなデータを持つか、どのような型かを決めます。
content
ディレクトリにconfig.ts
ファイルをつくり以下を記述します。
// src/content/config.ts
import { z, defineCollection } from 'astro:content';
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
date: z.number(),
title: z.string(),
description: z.string(),
thumbnail: z.string(),
tags: z.array(z.string()),
}),
});
export const collections = {
blog: blogCollection,
};
スキーマの中身はお好みで。ここでは投稿日、タイトル、ディスクリプション、サムネイル、タグを定義します。
date
はnumber
、title
はstring
など、ここで各スキーマの型を定義しています。
collectionsオブジェクトのキーに先ほど追加したコレクション名を、バリューにスキーマを定義した定数を設定することで完了です。
複数のコレクションを定義したり、サードパーティ製のコレクションスキーマを使用したり、などいろいろできるようです。詳細はドキュメントまで。
src/content/config.tsでモジュール'astro:content'またはそれに対応する型宣言が見つかりません。
とのエラーが出た場合は、ローカルサーバーを立て直すと解消されます。
コンテンツをつくる
ディレクトリも設定も終わればお次はコンテンツです。
コンテンツには.md
や.mdx
などが使えます。ここではなにかと便利な.mdx
を使用します。
先ほど定義したコレクションのスキーマをフロントマター内で指定し、コンテンツを記述します。
ファイル名はお好みで。ここでは投稿日にします。
// src/content/blog/230607.mdx
---
date: 2023-07-07
title: 'AstroのContent Collectionsでブログをつくる'
description: 'AstroのContent Collectionsはマークダウンを型安全に管理するための機能です。Content Collectionsを用いたブログの構築手順をご紹介します。'
thumbnail: 'astro_thumb.jpg'
tags: ['Astro']
---
// MDX内では各スキーマの値を{frontmatter.[キー]}で取得できる
# {frontmatter.title}
<img src={frontmatter.thumbnail} alt={frontmatter.title} />
Content Collectionsは`.md`や`.mdx`を型安全に管理するためのAstroの機能です。[email protected]で追加されました。
MDXの設定
MDXはMarkdown with JSXの略称で、その名の通りマークダウンの中でJSXが記述できます。
そのため、コンテンツ内にAstroコンポーネントを呼び出すことも可能です。詳細はドキュメントまで。
Astroで.mdx
を使うために@astrojs/mdx
をインストールします。
npx astro add mdx
インストールが完了したら適用します。
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
integrations: [mdx()],
});
お使いのエディターがVS Codeの場合、MDXをサポートさせるための設定をします。
// .vscode/settings.json
{
"files.associations": {
"*.mdx": "markdown"
}
}
MDXの設定はこれにて完了です。
コンテンツページをつくる
コンテンツができたのでページに表示させます。
pages
ディレクトリの中に[...slug].astro
ファイルをつくり、以下を記述します。
// pages/blog/[...slug].astro
---
import { getCollection } from 'astro:content';
import Layout from '../../layouts/Layout.astro';
export async function getStaticPaths() {
const blogEntries = await getCollection('blog');
return blogEntries.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
---
// [...slug].astroファイル内では各スキーマの値を{[プロップス].data.[キー]}で取得できる
<Layout title={entry.data.title} description={entry.data.description}>
<Content />
</Layout>
src/content/blog/230607.mdxをつくった場合、localhost:xxxx/blog/230607が動的にルーティングされます。
ローカルサーバーを起動してコンテンツのURLを入力するとコンテンツが表示されます🎉
コンテンツ一覧ページをつくる
残るは一覧ページです。
コンテンツ一覧を表示させたいファイルに以下を記述します。
// pages/blog/index.astro
---
import { getCollection } from 'astro:content';
import Layout from '../../layouts/Layout.astro';
const blogEntries = await getCollection('blog');
---
<Layout title='' description=''>
<ul>
{
blogEntries.map((blogPostEntry) => (
<li>
<a href={`/blog/${blogPostEntry.slug}`}>
<img src={blogPostEntry.data.thumbnail} alt={blogPostEntry.data.title} />
<p>{blogPostEntry.data.title}</p>
</a>
</li>
))
}
</ul>
</Layout>
これまたローカルサーバーを起動してつくったコンテンツのURLを入力するとコンテンツが表示されます🎉
おわりに
過ちを犯せばすぐに該当箇所のエラーが出るのでトラブルシューティングも安心。
SSGにも向き不向きがありますが、つくるサイトにハマればうまいこと開発・運用できるのではないでしょうか。
参考
Content Collections 🚀 Astro Documentation
Markdown & MDX 🚀 Astro Documentation