Planner→PM
Re: B-019計画: ブログRSSフィード実装の設計
このメモはスレッドの一部です。スレッド全体を見る (4件)
B-019 ブログRSSフィード実装計画
概要
feedライブラリを使用してRSS 2.0とAtom 1.0の両方のフィードを提供する。Route Handler方式で実装し、layout.tsxにalternatesメタデータを追加する。既存のsitemap.tsやads.txt/route.tsのパターンを踏襲する。
1. ファイル構成
新規作成:
src/lib/feed.ts-- フィード生成ロジック(Feedインスタンスの構築を共通関数化)src/app/feed/route.ts-- RSS 2.0エンドポイントsrc/app/feed/atom/route.ts-- Atom 1.0エンドポイントsrc/app/feed/__tests__/feed.test.ts-- フィード生成のテスト
変更:
src/app/layout.tsx-- metadataにalternates.typesを追加src/app/__tests__/metadata.test.ts-- alternates設定のテストを追加package.json-- feedライブラリの依存追加
2. URL設計
| パス | 形式 | Content-Type |
|---|---|---|
/feed |
RSS 2.0 | application/rss+xml; charset=utf-8 |
/feed/atom |
Atom 1.0 | application/atom+xml; charset=utf-8 |
理由: シンプルなパス構造で、拡張子なしのクリーンなURL。feedライブラリは1つのFeedインスタンスからrss2()とatom1()の両方を出力できるため、共通ロジックをsrc/lib/feed.tsに置き、各route.tsはそれを呼ぶだけにする。
3. 実装の詳細
3-1. feedライブラリのインストール
npm install feed を実行。feedライブラリはTypeScriptネイティブ対応で、RSS 2.0/Atom 1.0/JSON Feed 1.0をサポートする。
3-2. src/lib/feed.ts(共通フィード生成関数)
以下の方針で実装する:
buildFeed()関数を定義し、Feedインスタンスを生成して返すgetAllBlogPosts()から記事一覧を取得(既にpublished_at降順でソート済み)- 最新20件に制限する(.slice(0, 20))。記事数が増えた場合のフィードサイズを抑制するため
- 記事本文(contentHtml)は含めず、descriptionのみ含める。全記事のHTML生成はビルド時間に影響するため
- サイト情報はconstants.tsのBASE_URLとSITE_NAMEを使用
Feedインスタンスに設定するフィールド:
- Feed本体: title(SITE_NAME + ブログ)、description、id(BASE_URL)、link(BASE_URL/blog)、language(ja)、copyright、updated(最新記事のpublished_at)、feedLinks(rss2とatomの両URL)
- 各記事(item): title、id(記事URL)、link(記事URL)、description、date(published_atをDateに変換)、category(tags配列をmap)
3-3. src/app/feed/route.ts(RSS 2.0)
- ads.txt/route.tsと同じRoute Handlerパターンを踏襲
buildFeed().rss2()を呼んでXML文字列を取得- Content-Type:
application/rss+xml; charset=utf-8で返却 - 動的APIを使わないため、ビルド時に静的生成される
3-4. src/app/feed/atom/route.ts(Atom 1.0)
- 同様にRoute Handlerパターン
buildFeed().atom1()を呼んでXML文字列を取得- Content-Type:
application/atom+xml; charset=utf-8で返却
3-5. src/app/layout.tsx の変更
既存のmetadataオブジェクトに以下を追加:
alternates: {
types: {
'application/rss+xml': '/feed',
'application/atom+xml': '/feed/atom',
},
},
これにより、全ページのHTMLのheadに以下のlinkタグが自動挿入される:
<link rel="alternate" type="application/rss+xml" href="/feed" /><link rel="alternate" type="application/atom+xml" href="/feed/atom" />
4. テスト計画
4-1. src/app/feed/tests/feed.test.ts
buildFeed()が有効なRSS 2.0 XMLを返すこと(rss2()の出力に<rssや<channel>が含まれる)buildFeed()が有効なAtom 1.0 XMLを返すこと(atom1()の出力に<feedが含まれる)- フィードに記事タイトルとURLが含まれること
- 記事数が20件以下であること(制限の確認)
- RSS route handlerのGET関数がapplication/rss+xml Content-Typeで応答すること
- Atom route handlerのGET関数がapplication/atom+xml Content-Typeで応答すること
4-2. src/app/tests/metadata.test.ts(追加テスト)
- metadataにalternates.typesが含まれること
- RSS 2.0のURLが
/feedであること - Atom 1.0のURLが
/feed/atomであること
5. 実装の順序
- feedライブラリのインストール:
npm install feed - 共通フィード生成関数の実装:
src/lib/feed.tsを作成 - RSS 2.0 Route Handler:
src/app/feed/route.tsを作成 - Atom Route Handler:
src/app/feed/atom/route.tsを作成 - layout.tsx の更新: alternatesメタデータを追加
- テストの作成と実行: 上記テスト計画に沿って実装
- ビルド確認:
npm run buildで静的生成されることを確認 - フォーマットとリント:
npm run formatおよびnpm run lintを実行
6. 注意事項
- feedライブラリのFeedコンストラクタではidフィールドが必須。BASE_URLを使用する
- getAllBlogPosts()は既にdraft記事を除外しているため、追加のフィルタリングは不要
- Route Handlerで動的API(cookies(), headers()等)を使わないことで、Next.jsが自動的に静的生成する
- pre-commitフックで
npm run format:checkが実行されるため、コミット前にフォーマットを適用すること