前回からの続きです。
【Astro入門】ブログ記事と画像の最適なディレクトリ構成!「1記事1フォルダ」管理とslug設定
今回はブログのトップページに、新着記事を最新のものから10件取得して一覧表示させてみます。
src/pages/index.astroの編集
トップページである「src/pages/index.astro」の編集を行います。
コンポーネントスクリプト部分の編集
ページの上部にある「---」(コンポーネントスクリプト)の中に、記事のデータを取得して「日付の新しい順」に並び替え、最新の10件を取得するJavaScriptのコードを追加します。
// Astroが用意している「astro:content」ライブラリから「getCollection」の機能をインポートします。
import { getCollection } from 'astro:content';
// blogディレクトリの中身を全て取得する
const allPosts = await getCollection('blog');
// 取得した記事を「日付の新しい順(降順)」に並び替える
allPosts.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
// 新着記事を最新から10件だけを切り取って、recentPostsに入れる
const recentPosts = allPosts.slice(0, 10);
JavaScriptの解説
import { getCollection } from 'astro:content';
Astroが用意している「astro:content」ライブラリから「getCollection」の機能をインポートします。
const allPosts = await getCollection('blog');
- await
- 記事を取得する処理が終わるまで待機(一時停止)します。
- getCollection('blog')
- この一行を書くだけで、blogディレクトリ内にある全てのMarkdownファイルの情報(タイトルや日付、そして slug など)が取得され、リストとして allPosts に格納されます。
allPosts.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
allPostsに格納されている記事の、フロントマター部分に設定している「pubDate」(現在は年月日を設定中)の値を比較して、新しい順に並び替えます。
const recentPosts = allPosts.slice(0, 10);
並び替えられた全記事の中から、「0番目(一番上)から10個分」だけを切り取り、recentPosts という新しい配列に格納します。
HTML部分の編集(一覧の表示)
index.astro の下半分(<BaseLayout>の中)に、取得した記事を表示するための以下のコードを追加します。
<section style="margin-top: 40px;">
<h3>新着記事</h3>
<ul>
{
recentPosts.map((post) => {
// URLを短くする
const cleanSlug = post.slug.split('/').pop();
return (
<li style="margin-bottom: 10px;">
<a href={`/blog/${cleanSlug}/`}>{post.data.title}</a>
<span style="color: #666; font-size: 0.9em; margin-left: 10px;">
{post.data.pubDate.toLocaleDateString('ja-JP')}
</span>
</li>
);
})
}
</ul>
</section>
コードの解説
HTML部分の中に { } (波括弧)を書くことで、その中でJavaScriptを動かすことができます。
recentPosts.map((post) => { ... }):
recentPosts の中に入っている記事の数だけ、{}内の処理を繰り返して<li> タグを作成してくれます。
const cleanSlug = post.slug.split('/').pop();
これはURLをきれいに整えるための処理です。
- post.slug
- 記事のデータがあるディレクトリをslugとして認識します。
- 「src/content/blog/2026/03/09-blog」ディレクトリに記事を書いている場合は、「2026/03/09-blog」をslugとして認識します。
- split('/')
-
「/」(スラッシュ)を区切り文字として文字列を切り離します。
例:["2026", "03", "09-blog"] - pop()
- 分割したリストの中から一番最後(右端)のデータを取り出します。これにより、09-blog だけが cleanSlug に格納されます。
この結果がcleanSlugに格納されます。
※記事のフロントマターでslugが設定されている場合
記事のフロントマターで「slug: 2026-3-13」と行ったように直接設定している場合は、最初から「/」が含まれていないため、そのままの文字列が格納されます。
<a href={/blog/${cleanSlug}/}>{post.data.title}</a>
cleanSlugには記事のURL文字列が入っているので、正しい記事ページへ飛ぶリンクが完成します。
post.data.title は記事のフロントマターに書いたタイトル(title)です。
post.data.pubDate.toLocaleDateString('ja-JP')
フロントマターに記述した「pubDate」(日付のDateオブジェクト)を、私たちが見慣れた「日本の形式(ja-JP)」の文字列に変換します。
- 変換前: Fri Mar 13 2026 09:00:00 GMT+0900
- 変換後: 2026/3/13
完成した「src/pages/index.astro」
最終的なコードは以下のようになります。
---
import BaseLayout from '../layouts/BaseLayout.astro';
// Astroのastro:contentからgetCollectiionツールをインポート
import { getCollection } from 'astro:content';
// blogディレクトリの中身を全て取得する
const allPosts = await getCollection('blog');
// 取得した記事を「日付の新しい順(降順)」に並び替える
allPosts.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
// 新着記事を最新から10件だけを切り取って、recentPostsに入れる
const recentPosts = allPosts.slice(0, 10);
---
<BaseLayout>
<main>
<h2>こんにちは!</h2>
<p>何も渡さなくても、自動で「Game Life」とデフォルト説明文が適用されます!</p>
<section style="margin-top: 40px;">
<h3>新着記事</h3>
<ul>
{
recentPosts.map((post) => {
// URLを短くする魔法(前回と同じ!)
const cleanSlug = post.slug.split('/').pop();
return (
<li style="margin-bottom: 10px;">
<a href={`/blog/${cleanSlug}/`}>{post.data.title}</a>
<span style="color: #666; font-size: 0.9em; margin-left: 10px;">
{post.data.pubDate.toLocaleDateString('ja-JP')}
</span>
</li>
);
})
}
</ul>
</section>
</main>
</BaseLayout>
このようにトップページに新着記事が表示されるようになりました。



コメント