背景
このサイトの開発ブログはこれまで /blog というURLで公開していました。今回、/blog パスに別の新機能を実装する予定が生まれたため、既存の開発ブログを /devblog へ移行することにしました。
単にページファイルのディレクトリを変えるだけでなく、blog という名前自体を完全に解放することが目標でした。将来の新機能が blog という名前のルーティングやコンテンツコレクションを自由に使えるよう、名前空間ごと空けるアプローチです。
移行した範囲
今回の変更は URL だけでなく、Astro の内部構造にも及びました。
ディレクトリの移動:
- ページルーティング(
src/pages/blog/→src/pages/devblog/) - コンテンツコレクション(
src/content/blog/→src/content/devblog/)
コード内の参照の変更:
- Astro の
getCollection('blog')→getCollection('devblog')への書き換え - RSS フィード URL(
/blog/rss.xml→/devblog/rss.xml) - wiki 自動リンクの生成ロジック(
/blog/wiki/→/devblog/wiki/) - サイトマップ内の URL 列挙
- About ページなど各所のナビゲーションリンク
意図的に変えなかったもの:
- データベースのテーブル名(URL とは無関係なため)
/blog→/devblogの後方互換リダイレクト(/blogを新機能用に完全解放するため、あえて追加しない)
後から発覚した漏れ
初回の移行後、ブランチプレビューで確認したところ、一覧ページの記事リンクがすべて 404 になっていました。
原因は、テンプレートリテラル内の /blog パスが置換の対象から漏れていたことでした。
// 修正前(一覧ページのリンク生成部分)
`/blog/${post.slug}`
`/blog?category=${encodeURIComponent(cat)}`
// 修正後
`/devblog/${post.slug}`
`/devblog?category=${encodeURIComponent(cat)}`
通常の文字列リテラル('/blog/')は sed で一括置換できていましたが、バッククォートで始まるテンプレートリテラルはパターンに含めていなかったため見落としていました。
また個別記事ページでは、カテゴリーのリンク形式が古い /blog/category/xxx というパス形式のまま残っていました。現在のサイトではカテゴリーはクエリパラメータ形式(/devblog?category=xxx)で処理されているため、形式ごと変更する必要がありました。
// 修正前(旧パス形式)
`/blog/category/${category}`
// 修正後(クエリパラメータ形式)
`/devblog?category=${encodeURIComponent(category)}`
encodeURIComponent() を追加したのは、カテゴリー名に日本語が含まれる場合に URL エンコードが必要なためです。
Astro のコンテンツコレクションと URL の分離
今回の作業で改めて確認したのは、Astro においてページの URL とコンテンツコレクション名は別物だということです。
- URL のルーティング →
src/pages/配下のディレクトリ名で決まる - コンテンツコレクション名 →
src/content/配下のディレクトリ名で決まる - コレクションの参照 → コード内の
getCollection('コレクション名')で決まる
src/pages/devblog/ を作っただけでは getCollection('blog') は変わらず古いコレクションを参照したままになります。コードの参照も getCollection('devblog') に書き換えるとともに、src/content/devblog/ へのディレクトリ移動も必要でした。
移行後の確認ポイント
/devblogでブログ一覧が表示される- 記事個別ページのリンクが正しく
/devblog/を指している - カテゴリークリックで
/devblog?category=xxxへ遷移する - RSS フィード(
/devblog/rss.xml)が正常に返る /blogにアクセスすると 404(意図した動作)