開発blog-platform完了
パンくずメニューとディレクトリ一覧機能の実装
概要
Nuxt Content + MDX サイトに、パンくずメニューとディレクトリ一覧表示機能を追加しました。
実装した機能
1. パンくずメニュー (Breadcrumb.vue)
場所: apps/web/app/components/Breadcrumb.vue
機能:
- 現在のURLパスに基づいてパンくずリストを自動生成
- 最後の項目(現在のページ)はリンクなしで表示
- 中間パスはすべてリンク付きで表示
実装のポイント:
// 最後の項目のみリンクなし
<NuxtLink v-if="index < breadcrumbs.length - 1" :to="item.path">
{{ item.label }}
</NuxtLink>
<span v-else aria-current="page">{{ item.label }}</span>
2. ディレクトリ一覧表示
場所: apps/web/app/pages/[...slug].vue
機能:
- ディレクトリパスにアクセスした際に、配下の記事一覧を表示
- 記事が存在しない場合は "Not Found" を表示
重要な問題と解決策:
問題: queryCollection で取得した記事の _path が null
現象:
const articles = await queryCollection("pages").all();
// articles[0]._path === null (すべて null)
原因:
- Nuxt Content の記事オブジェクトは、
_pathプロパティではなくpathプロパティを持っている
解決策:
// ❌ 間違い
page._path?.startsWith(docPath.value + "/")
// ✅ 正しい
const pagePath = page.path || page._path;
pagePath.startsWith(docPath.value + "/")
最終的な実装:
const { data: allPages } = await useAsyncData(
'all-pages-for-dir',
() => queryCollection("pages").all()
);
const articles = computed(() => {
if (!allPages.value) return [];
return allPages.value.filter(page => {
const pagePath = page.path || page._path;
if (!pagePath) return false;
return pagePath.startsWith(docPath.value + "/") && pagePath !== docPath.value;
});
});
3. 記事一覧テーブルコンポーネント化
場所: apps/web/app/components/ArticleTable.vue
機能:
- タイトル、作成日、タグを表形式で表示
- ページネーション機能付き
- 20件以下の場合はページネーションを非表示
使用箇所:
- インデックスページ (
apps/web/app/pages/index.vue) - ディレクトリ一覧ページ (
apps/web/app/pages/[...slug].vue)
実装のポイント:
<!-- ページネーションは記事が20件を超える場合のみ表示 -->
<div v-if="totalPages > 1" class="pagination">
<!-- ... -->
</div>
トラブルシューティング
問題1: 開発サーバーのキャッシュ問題
現象:
- ファイルを修正しても古いエラーが表示され続ける
[vue/compiler-sfc] Unexpected tokenエラーが消えない
原因:
- Nuxt の開発サーバーが古いコンパイル結果をキャッシュしている
解決方法:
- 開発サーバーを停止 (Ctrl+C)
.nuxtフォルダを削除(オプション)pnpm run devで再起動
問題2: 正規表現での置換ミス
現象:
replace_regexで意図しない部分まで削除されてしまった- スクリプトセクションに余分な閉じ括弧が残った
教訓:
- 複雑な正規表現は慎重に使用する
- 置換後は必ずファイル全体を確認する
- 重要な変更の前にはバックアップを取る
ファイル構成
apps/web/app/
├── components/
│ ├── Breadcrumb.vue # パンくずメニュー
│ ├── ArticleTable.vue # 記事一覧テーブル
│ ├── DocPage.vue # 記事表示ページ
│ └── TableOfContents.vue # 目次
├── pages/
│ ├── index.vue # トップページ
│ └── [...slug].vue # 動的ルート(記事・ディレクトリ一覧)
使用方法
パンくずメニュー
パンくずメニューは自動的に表示されます。URLパスに基づいて生成されます。
例:
/2025-10-06/sns-principlesの場合Home / 2025-10-06 / sns-principlesHomeと2025-10-06はリンク付きsns-principlesはリンクなし(現在のページ)
ディレクトリ一覧
ディレクトリパス(例: /2025-10-06)にアクセスすると、配下の記事が自動的に一覧表示されます。
表示形式:
- タイトル(記事へのリンク)
- 作成日
- タグ
今後の改善案
- パンくずメニューのカスタマイズ
- セグメントのラベルをカスタマイズできるようにする
- アイコンの追加
- ディレクトリ一覧の拡張
- ソート順の変更機能
- フィルター機能
- 説明文の表示
- パフォーマンス最適化
- 記事一覧のキャッシング
- 遅延読み込み