はじめに
ブログを購読していただくために便利な RSS と Atom のフィード情報を生成する方法を紹介します。
Next.js 向けにカスタマイズされたパッケージは現状で見つからないため、Node.js 向けのパッケージである feed
を今回は利用します。
成果物
以下のような3つのファイルが生成されることを目標とします。
/rss/feed.xml
/rss/atom.xml
/rss/feed.json
feed を採用した理由
Next.js で RSS や Atom のフィード情報を生成する場合の情報を調査したときに、
Zenn を開発されている @catnose さんの
こちらの記事がとても参考になりました。
こちらの記事では
rss
というパッケージを利用されており、こちらは Node.js の RSS 生成系ではメジャーなようでしたが、最新の更新が4年前でした。
それに対して、以下の参考記事で紹介されたいた feed
というパッケージが更新日も4ヶ月前と比較的新しくメンテナンスもされているようでしたので、今回はこちらの feed
を採用することにしました。
rss
と feed
の Weekly Downloads を見ると feed
の方が少し多い程度です。
バージョン情報
- Node.js:15.11.0
- React:17.0.2
- Next.js:10.2.2
- feed:4.2.2
- marked:2.0.5
feed を導入
feed のインストール
以下のコマンドで簡単にインストールができます。
# npm の場合
npm install --save-dev feed
# yarn の場合
yarn add --dev feed
また、Markdown のファイルを利用している時はフィード情報作成時に HTML ファイルへ変換する必要があるため、marked
などのパッケージも利用します。
# npm の場合
npm install --save-dev marked
# yarn の場合
yarn add --dev marked
フィード情報を集約する関数
以下のようにフィード情報を集約する関数 generatedRssFeed
を作成しました。
process.env
で環境変数から情報を取得しており、これらは .env
ファイル内で定義しています。
// src/lib/feed.ts
import fs from 'fs';
import { Feed } from 'feed';
import marked from 'marked';
function generatedRssFeed(): void {
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || '';
const date = new Date();
// author の情報を書き換える
const author = {
name: 'sample',
email: 'sample@sample.com',
link: 'https://...com',
};
// デフォルトになる feed の情報
const feed = new Feed({
title: process.env.NEXT_PUBLIC_BASE_NAME || '',
description: process.env.NEXT_PUBLIC_BASE_DISC,
id: baseUrl,
link: baseUrl,
language: 'ja',
image: `${baseUrl}/favicon.png`, // image には OGP 画像でなくファビコンを指定
copyright: `All rights reserved ${date.getFullYear()}, ${author.name}`,
updated: date,
feedLinks: {
rss2: `${baseUrl}/rss/feed.xml`,
json: `${baseUrl}/rss/feed.json`,
atom: `${baseUrl}/rss/atom.xml`,
},
author: author,
});
// ローカルファイルや API 経由などでファイルのデータを取得する関数を書く
const posts = getPosts(...);
// feed で定義した情報から各記事での変更点を宣言
posts.forEach((post) => {
// post のプロパティ情報は使用しているオブジェクトの形式に合わせる
const url = `${baseUrl}/${post.id}`;
feed.addItem({
title: post.title,
description: post.description,
id: url,
link: url,
content: marked(post.content), // marked で markdown => html
date: new Date(post.date),
});
});
// フィード情報を public/rss 配下にディレクトリを作って保存
fs.mkdirSync('./public/rss', { recursive: true });
fs.writeFileSync('./public/rss/feed.xml', feed.rss2());
fs.writeFileSync('./public/rss/atom.xml', feed.atom1());
fs.writeFileSync('./public/rss/feed.json', feed.json1());
}
export default generatedRssFeed;
上記のファイルに編集が必要な点をコメントで書いておきました。
必要な情報は基本的に揃っているため、post
の形式などを合わせていただく程度で大丈夫です。
ここで、
image
に指定するファビコンに関して注意点があります。
通常、ファビコンは
favicon.ico
といった形式で保存しますが、RSS フィードの形式が正しいか確認するために
W3C Feed Validation Service(
https://validator.w3.org/feed/) を利用して確認すると、以下のような警告いが表示されます。
ファビコンを含めた画像では png
, jpeg
, gif
といった形式の必要性があるらしく、RSS フィード用の画像はこれらのフォーマットを使用しておくことをお勧めします。
fwywd では RSS フィード用だけに png
形式のファビコン画像を用意しています。
ビルド時にフィード情報を自動的に更新
フィード情報を生成する generatedRssFeed
という関数を作成し、こちらを SSG のビルド時に利用するためには以下のようにトップページの getStaticProps
で実行すると良いでしょう。
// src/pages/index.tsx
// ...
export const getStaticProps: GetStaticProps = async () => {
// フィード情報の生成
generatedRssFeed();
// ...
return { props: { ... } };
};
動作確認
ローカルでのテストは yarn dev
でサーバーを立ち上げ、localhost:3000/
のページへアクセス後、以下3つのページが生成されているか確認してみましょう。
/rss/feed.xml
/rss/atom.xml
/rss/feed.json
これで動作確認が完了しました。
補足:URL が localhost:3000
となっている問題はローカル用の環境変数を使っているためであり、本番環境ではドメインが反映されるように私の手元では .env.development
と .env.production
に分けています。
Git の対象外に設定しておこう
ローカル環境で開発を行うと、自動的に3つのファイルが生成されてしまい、これが Git の管理対象になるとコンフリクトを起こしたり、レビューの邪魔をします。
以下のように管理の対象外として設定しておきましょう。
# .gitignore
...
# rss feed
/public/rss/atom.xml
/public/rss/feed.json
/public/rss/feed.xml
...
Google Search Console へ登録
SEO 対策として Google エンジンの流入をスムーズにするために生成した
rss/feed.xml
と
rss/atom.xml
を
Google Search Console へ登録しておくことをオススメします。
おわりに
超お手軽とまではいきませんが、feed
を利用することで RSS や Atom のフィード情報を反映することができました。
最近では Slack へ RSS フィードの設定もできるようになっており、技術チームではこれを使って日々最新の情報をキャッチアップすることも多いので、余裕があれば設定しておくことをオススメします。