Ask and Learn

给 next.js 添加 rss 订阅

我的博客程序是用 next.js 写的,之前一直没有做订阅功能,今天晚上心血来潮,整了一整。

这里借助的是 feed 这个 package.

yarn add feed

在 pages 下面创建一个 feed.xml.js 的文件。

// ...
import { Feed } from "feed"

const Page = () => {}

export async function getServerSideProps(context) {
  const res = context.res
  if (!res) {
    return
  }

  const posts = await getRecentPosts(1)
  const feed = createFeed(posts)
  res.setHeader("Content-Type", "text/xml")
  res.write(feed.rss2())
  res.end()

  return {
    props: {}
  }
}

export default Page

这里是需要 getServerSideProps 来服务端渲染这个 xml 格式的响应内容,另外两点需要注意的是

  1. 你需要 export 一个空的 Page, 不然请求会报错
  2. 需要设置 Content-Typetext/html, 然后通过 res.write 生成的 xml 写入 response body.
  3. getServerSideProps 需要返回一个空的 props, 不然会有一个 warning

createFeed 方法的实现如下

const createFeed = posts => {
  const siteURL = "https://anl.gg"
  const date = new Date()
  const author = {
    name: "greatghoul",
    email: "greatghoul@gmail.com",
    link: "https://github.com/greatghoul",
  }

  const feed = new Feed({
    title: "Ask and Learn",
    description: "greatghoul 的博客,记录开发心得,分享有趣的应用和服务",
    id: siteURL,
    link: siteURL,
    favicon: `${siteURL}/favicon.ico`,
    copyright: `All rights reserved ${date.getFullYear()}, greatghoul`,
    updated: date,
    feedLinks: {
      rss2: `${siteURL}/feed.xml`
    },
    author
  })

  posts.forEach((post) => {
    const url = `${siteURL}/posts/${post.id}`

    feed.addItem({
      title: post.title,
      id: url,
      link: url,
      description: post.brief,
      content: post.content,
      author: [author],
      contributor: [author],
      date: new Date(post.published_at),
    })
  })

  return feed
}

其实 feed 这个 package 除了 rss2,还支持其他格式,详见官方文档

console.log(feed.rss2());
// Output: RSS 2.0

console.log(feed.atom1());
// Output: Atom 1.0

console.log(feed.json1());
// Output: JSON Feed 1.0

上面这些做好后,我们还是只能通过 url 来访问 feed,你可能还需要添加页面链接以及 head link.

<a href="/feed.xml">FEED</a>
<Head>
  <link rel="alternate" type="application/rss+xml" title="Feed for Ask and Learn" href="/feed.xml" />
</Head>

参考资料