このブログのRSSを出力したい機運が高まってきたので、Next.jsでのRSSフィードの出力方法を解説します。
他に良い方法があるかもしれないです。よければ教えてください!
RSSフィードを出力するのに使えそうなnpmが2つあります。 rssとfeedですが、今回はfeedを使います。
参考にしたcatnoseさんはrss
の方を使ってました。どちらでもやりたいことはできるのでどちら使っても良いと思います。
feed
にした理由は
rss
の方が最終リリースが5年前と古いrss
の方が依存が多い
mime-typesとxmlの2つ。xmlの方は最終更新日が6年前である。feed
は依存しているのがxml-jsだけ
依存は少ないほうがやっぱり良いですよね。
ってことでやっていきます。
手順
①feedを追加する
$ yarn add feed
②RSSフィードを出力するページを作る
ほぼ、参考にしたcatnoseさんの記事と同じです。
pages/feed.tsx
import { GetServerSidePropsContext } from 'next'import { generateFeed } from '@/libs/api/feed'
export const getServerSideProps = async ({ res,}: GetServerSidePropsContext) => { const xml = await generateFeed() // 実際にRSSフィードを生成する処理(後述)
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 = () => nullexport default Page
③RSSフィードを生成する処理を作る
libs/feed/index.ts
import { Feed } from 'feed'import dayjs from 'dayjs'
export const generateFeed = async () => { const baseUrl = 'https://www.deg84.com'
const feed = new Feed({ title: "deg84's blog", description: '', id: baseUrl, link: baseUrl, language: 'ja', copyright: `© 2020 deg84`, updated: dayjs().toDate(), // 日付系はdayjsを使うことにしているので。new Date()でも良い。 author: { name: 'deg84', }, feed: `${baseUrl}/feed`, })
const posts = await getPosts() // 何らかの方法で記事一覧を取得する
posts.forEach(post => { const url = `${baseUrl}/${post.slug}` feed.addItem({ title: post.title, description: post.description, content: post.content, id: url, link: url, date: dayjs(post.publishedAt).toDate(), }) })
return feed.rss2() // Atom形式でデータが欲しい場合は`feed.atom`を使う。}
以上で出力できるようになってるはずです。
結果
<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <title>deg84's blog</title> <link>https://www.deg84.com</link> <description></description> <lastBuildDate>Wed, 18 May 2022 09:05:41 GMT</lastBuildDate> <docs>https://validator.w3.org/feed/docs/rss2.html</docs> <generator>https://github.com/jpmonette/feed</generator> <language>ja</language> <copyright>© 2020 deg84</copyright> <atom:link href="https://www.deg84.com/feed/" rel="self" type="application/rss+xml"/> <item> <title><![CDATA[ Next.jsで作ってるブログでRSSフィードを出力する ]]></title> <link>https://www.deg84.com/create-rss-feed-with-nextjs</link> <guid>https://www.deg84.com/create-rss-feed-with-nextjs</guid> <pubDate>Wed, 18 May 2022 09:30:00 GMT</pubDate> <description><![CDATA[ descriptionが入ります ]]></description> <content:encoded><![CDATA[ contentが入ります ]]></content:encoded> </item> <!-- 以下同じような感じで一覧が並ぶ --> </channel></rss>
出力されているXMLはW3C Feed Validation Service, for Atom and RSS等でチェックしておきます。
さいごに
昔はHTMLのheadにlinkでRSSフィードのURLを張ってた気がするんだけど最近それはやらない系なんだろうか?
<link rel="alternate" type="application/rss+xml" title="deg84's blog feed" href="https://www.deg84.com/feed/" />
こんなやつ