【Nuxt.js】SSGでフィードを自動生成する

先日,サイトマップを自動生成しましたが,新規記事の投稿を通知するにはフィードもあると便利ですね.

WordPress時代のフィードをGoogleに設定したままだったので更新したい.

SSR のウェブサイトであれば @nuxtjs/feed で対応できるのですが,今回は SSG なのでとある理由により利用できません.

SSG製サイトでのフィード生成

@nuxtjs/feed は Axios を使用していてこのままではローカルで生成できないのと,フックによって generate 前に実行するようになっているので,最新の内容で更新できないという問題があるようです.

そのため,現状 SSG の場合は自作モジュールで対応する必要があります.

環境

  • Node.js: v13.12.0
  • npm: v6.14.8
  • @nuxt/content: v1.9.0
  • feed: v4.2.1

実装例

@/modules/feed.js
const fs = require('fs')
const { Feed } = require('feed')

const host = 'https://<your-site.com>'

module.exports = function () {
  this.nuxt.hook('generate:done', async (generator) => {
    const { $content } = require('@nuxt/content')
    const articles = await $content('articles')
      .sortBy('createdAt', 'desc')
      .limit(10)
      .fetch()

    const feed = new Feed({
      title: 'title',
      description: 'description',
      id: host,
      link: host,
    })

    const contents = async () => {
      const contentArray = await Promise.all(
        articles.map(async (article) => {
          const content = await fs.readFile(
            __dirname + `/../dist/${article.slug}/index.html`
          )
          return content
        })
      )
      return contentArray
    }

    articles.forEach((article, i) => {
      const url = `${host}/${article.slug}`
      feed.addItem({
        title: article.title,
        id: url,
        link: url,
        description: article.description
      })
    })

    await fs.writeFile(
      __dirname + '/../dist/rss.xml',
      feed.rss2(),
      (err, result) => {
        if (err) console.log(err)
      }
    )

    console.log('Generated a feed.')
  })
}

生成すると https://<your-site.com>/rss.xml でフィードにアクセスできます.

feed パッケージを使用しているので設定はこれに準じており,必要に応じて項目が増やせます.

また,生成できるのは RSS 2.0 だけでなく,Atom 1.0,JSON 1.0 でも生成できます.

nuxt.config.js
export default {
  ...
  modules: [
    '~/modules/feed.js'
  ]
}

最後に

これでフィードを通じて記事更新を通知できるようになりました.

参考