📰
Next.jsで動的にRSSフィードを生成する
先日Next.jsでXML Sitemapを生成する方法を書きました。同じ要領でRSSフィードの実装もできるので記事にしておきます。
Next.jsのgetServerSidePropsで動的にRSSフィードを生成
Next.js(TypeScript)のPageコンポーネントの中で実装を行います。例として/feedにアクセスしたときにRSSフィードが表示されるように/pages/feed.tsxというファイルを作成します。
getServerSidePropsを使う理由
このサンプルでは、RSSデータの生成からレスポンスの返却までgetServerSidePropsの中で行います。getServerSidePropsは本来はPageコンポーネント内で使うpropsを取得するためのものですが、ここではpageコンポーネントを介さずに直接レスポンスを返却してしまいます。
というのもPageコンポーネント内でHTMLやXMLを返しても、_app.tsxや_document.tsxの中に埋め込まれることになるため、レイアウトやメタタグなど余計なものが混じってしまうためです。
サンプルコード
pages/feed.tsx
import { GetServerSidePropsContext } from 'next';
export const getServerSideProps = async ({ res }: GetServerSidePropsContext) => {
const xml = await generateFeedXml(); // フィードのXMLを生成する(後述)
res.statusCode = 200;
res.setHeader('Cache-Control', 's-maxage=86400, stale-while-revalidate'); // 24時間キャッシュする
res.setHeader('Content-Type', 'text/xml');
res.end(xml);
return {
props: {},
};
};
const Page = () => null;
export default Page;
getServerSidePropsの引数でresを受け取ることができるので、HeaderにContent-TypeやCache-Controlをつけたうえでres.end(RSSフィードの中身)という形でレスポンスを返します。
RSSフィードの生成
あとはRSSフィード自体の生成ですが、ここではrssというnpmライブラリを使うことにします.
$ npm install rss
$ npm install --save-dev @types/rss
import RSS from 'rss';
async function generateFeedXml() {
const feed = new RSS({
title: "タイトル",
description: "説明",
site_url: "サイトのURL",
feed_url: "フィードページのURL",
language: 'ja',
});
// 例としてpostsを含めるイメージ
// このあたりの書き方はライブラリのドキュメントを参考にしてください
const { posts } = await getPosts();
posts?.forEach((post) => {
feed.item({
title: post.title,
description: post.description,
date: new Date(post.createdAt),
url: `${サイトのURL}/${post.path}`,
});
})
// XML形式の文字列にする
return feed.xml();
}
これをさきほどのgetServerSidePropsの中から呼べば完了です。生成したRSSが正しい形式になっているかどうかはW3CのFeed Validation Service等でチェックする良いでしょう。
Discussion
とても参考になる記事有難うございます!
本当に些細な箇所ですが、一連の流れ的に
は
return feed.xml();になりそうです。あっ…、ありがとうございます!修正しました。
お手数おかけしました!有難うございます!