0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Astro タグ別記事一覧ページの作り方

Posted at

ここでは、「Content Collections API」とMarkdownの tags フロントマターを使って、タグごとの記事一覧ページを作成する手順を紹介します。

前提:

  • Content Collections APIを使ってブログ記事 (blog コレクション) を管理していること。
  • 各記事のMarkdownファイルのフロントマターに tags 配列が設定されていること (例: tags: ["Astro", "初心者"])。

タグ別記事一覧ページの作成手順

1.動的ルートファイルの作成 (src/pages/tags/[tag].astro)

まず、タグごとのページを生成するための動的ルートファイルを作成します。src/pages/tags/ ディレクトリ(なければ作成)に [tag].astro という名前でファイルを作成します。[tag] の部分がURLのタグ名になります。

your-project/
└── src/
    ├── content/
    │   └── blog/
    ├── pages/
    │   ├── blog/
    │   ├── tags/         <-- このディレクトリを作成
    │   │   └── [tag].astro <-- このファイルを作成
    │   └── [...slug].astro (個別記事ページ)
    └── layouts/

2.getStaticPaths の実装 (タグと記事リストの生成)

作成した src/pages/tags/[tag].astro ファイルを開き、getStaticPaths 関数を実装します。この関数は、存在するすべてのタグに対してページを生成するようにAstroに指示し、各ページに必要なデータを渡します。

---
// src/pages/tags/[tag].astro
import { getCollection } from 'astro:content';
import type { CollectionEntry } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro'; // 適切なレイアウトを指定

export async function getStaticPaths() {
  const allPosts = await getCollection('blog');

  // 1. 全記事からユニークなタグを集める
  const uniqueTags = new Set<string>();
  allPosts.forEach((post) => {
    // post.data.tags が存在する場合のみ処理 (?. オプショナルチェイニング)
    post.data.tags?.forEach((tag) => {
      uniqueTags.add(tag); // Setが自動で重複を除外
    });
  });

  // 2. 各タグに対応するページ情報を作成
  return Array.from(uniqueTags).map((tag) => {
    // 3. このタグが含まれる記事だけをフィルタリング
    const filteredPosts = allPosts.filter((post) =>
      post.data.tags?.includes(tag)
    );
    // 4. ページのパスと渡すデータを返す
    return {
      params: { tag: tag }, // URLの [tag] 部分になる値
      props: {
        tag: tag, // ページコンポーネントで使うタグ名
        posts: filteredPosts, // このタグの記事リスト
      },
    };
  });
}

// getStaticPathsから渡されたデータを受け取る
const { tag, posts } = Astro.props;
// 記事を日付順にソート (任意)
posts.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());

// URLを決定するヘルパー関数 (個別記事ページへのリンク用、前の手順から流用)
function getPostUrl(post) {
  if (post.data.url) {
    return `/${post.data.url}/`;
  }
  return `/blog/${post.slug}/`;
}
---
  • getCollection('blog') で全記事を取得します。
  • Set を使って、すべての記事からユニークなタグを集めます。post.data.tags?.forEach?.tags がない記事でもエラーにならないようにします。
  • 集めたユニークなタグ (uniqueTags) それぞれについて、map で処理します。
  • filter を使って、そのタグが含まれる記事 (filteredPosts) を抽出します。
  • params: { tag } でページのURL (例: /tags/Astro/) を定義し、props: { tag, posts } でページコンポーネントにタグ名とそのタグの記事リストを渡します。

3.タグ別記事リストの表示

getStaticPaths の下に、ページのHTMLテンプレート部分を記述します。Astro.props から渡された tagposts を使って一覧を表示します。

---
// --- 上記の getStaticPaths と props の受け取りコード ---
---
<BaseLayout title={`タグ: ${tag}`}>
  <h1>タグ: 「{tag}」 の記事一覧</h1>

  <ul>
    {posts.map((post) => (
      <li>
        <a href={getPostUrl(post)}>{post.data.title}</a>
        <span style="font-size: 0.8em; margin-left: 8px;">
          ({post.data.pubDate.toLocaleDateString()})
        </span>
      </li>
    ))}
  </ul>

  <p>
    <a href="/tags/">すべてのタグ一覧へ</a>
  </p>
</BaseLayout>
  • Astro.props から tagposts を受け取ります。
  • 受け取った posts 配列を map でループ処理し、各記事へのリンクとタイトルなどを表示します。記事へのリンクは、前の手順で定義した getPostUrl ヘルパー関数を使うと便利です。
  • ページ全体を適切なレイアウトコンポーネント (<BaseLayout> など) で囲みます。

4.全タグ一覧ページの作成 (src/pages/tags/index.astro)

すべてのタグをリスト表示するページもあると便利です。src/pages/tags/index.astro を作成します。

---
// src/pages/tags/index.astro
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro'; // 適切なレイアウトを指定

const allPosts = await getCollection('blog');
const uniqueTags = new Set<string>();
allPosts.forEach((post) => {
  post.data.tags?.forEach((tag) => {
    uniqueTags.add(tag);
  });
});
const sortedTags = Array.from(uniqueTags).sort(); // アルファベット順にソート (任意)
---
<BaseLayout title="すべてのタグ">
  <h1>すべてのタグ一覧</h1>
  <ul>
    {sortedTags.map((tag) => (
      <li>
        <a href={`/tags/${tag}/`}>{tag}</a>
      </li>
    ))}
  </ul>
</BaseLayout>
  • タグ別ページと同様に全記事からユニークなタグを集めます。
  • 集めたタグを map でループし、各タグのタグ別一覧ページ (/tags/タグ名/) へのリンクを生成します。

5.開発サーバーで確認

ターミナルで開発サーバーを起動します。

npm run dev
# または pnpm dev, yarn dev

ブラウザで以下のURLにアクセスして確認してみましょう。

  • 全タグ一覧ページ: http://localhost:4321/tags/
  • タグ別記事一覧ページ: http://localhost:4321/tags/Astro/ (例: Astro タグのページ)

全タグ一覧ページが表示され、各タグをクリックするとそのタグが付いた記事の一覧ページに移動できれば成功です!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?