rss

Gatsbyで作ったブログでRSSを配信する

2021年03月23日

このブログでのRSSの配信をはじめました。

cf3b226d6866835d

gatsby-plugin-feedはローカルのMarkdownファイルで記事を管理しているのであれば、インストールしてgatsby-config.jsで読み込むだけでフィードを生成してくれる優れ物なのですが、ContenfulやWordPressなどから記事を取得している場合はGraphQLクエリーを投げてRSSの各タグに割り当てるようにする設定が必要です。

gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `Lon Sagisawa`,
    description: `private blog of Lon Sagisawa`,
    siteUrl: `https://lon.sagisawa.me`
  },
  plugins: [
  module.exports = {
    ...
    resolve: `gatsby-plugin-feed`,
    options: {
      query: `
        {
          site {
            siteMetadata {
              description
              siteUrl
              title
              site_url: siteUrl
            }
          }
        }
      `,
      feeds: [
        {
          serialize: ({ query: { site, allContentfulPost } }) => {
            return allContentfulPost.edges.map(edge => {
              return Object.assign({}, edge.node, {
                description: edge.node.description.description,
                date: edge.node.date,
                url: site.siteMetadata.siteUrl + edge.node.prefix + edge.node.slug,
                guid: site.siteMetadata.siteUrl + edge.node.prefix + edge.node.slug,
                custom_elements: [{ "content:encoded": edge.node.body.childMarkdownRemark.html }],
              })
            })
          },
          query: `
            {
              allContentfulPost(sort: {order: DESC, fields: date}) {
                edges {
                  node {
                    title
                    date
                    prefix: date(formatString: "/YYYY/MM/")
                    description {
                      description
                    }
                    slug
                    body {
                      childMarkdownRemark {
                        html
                      }
                    }
                  }
                }
              }
            }
          `,
          output: "/rss.xml",
          title: "Lon Sagisawa :: RSS feed",
        }
      ]
    },
    ...
  ]
}

ながーーーい設定でGraphQLクエリーも2つありますが、ひとつひとつ見ていきましょう。まずsiteMetadataのオブジェクト内でサイトの基本的な情報をいくつか定義しておきます。ひとまずタイトル、概要、URLの3つを。

siteMetadata: {
  title: `Lon Sagisawa`,
  description: `private blog of Lon Sagisawa`,
  siteUrl: `https://lon.sagisawa.me`
},

あとでフィードの生成に必要になります。

次にgatsby-plugin-feedを読み込んで、先程のsiteMetadataをGraphQLクエリーで早速呼び出します。

resolve: `gatsby-plugin-feed`,
options: {
  query: `
    {
      site {
        siteMetadata {
          description
          siteUrl
          title
          site_url: siteUrl
        }
      }
    }
  `,

feedsオブジェクト内の設定でフィードの生成にまつわる設定をします。serializeはとりあえず後回しにして、queryを見てみましょう。ここでContentfulからデータを引き出しています。

query: `
  {
    allContentfulPost(sort: {order: DESC, fields: date}) {
      edges {
        node {
          title
          date
          prefix: date(formatString: "/YYYY/MM/")
          description {
            description
          }
          slug
          body {
            childMarkdownRemark {
              html
            }
          }
        }
      }
    }
  }
`,

要るのはタイトル、日時、概要、HTML形式の本文、そして記事個別のURLを生成するのに必要な情報です。このブログの記事のURLは/YYYY/MM/slugという形式にしているので、prefixとして投稿の/YYYY/MMの部分を引っ張ってきています。

serializeの部分でフィードの各情報と先程の2つのクエリーで呼び出した各情報を紐付けていきます。よく見るとgatsby-node.jsでの記事ページ生成と似たような構造になっているのがおわかりいただけると思います。

serialize: ({ query: { site, allContentfulPost } }) => {
  return allContentfulPost.edges.map(edge => {
    return Object.assign({}, edge.node, {
      description: edge.node.description.description,
      date: edge.node.date,
      url: site.siteMetadata.siteUrl + edge.node.prefix + edge.node.slug,
      guid: site.siteMetadata.siteUrl + edge.node.prefix + edge.node.slug,
      custom_elements: [{ "content:encoded": edge.node.body.childMarkdownRemark.html }],
    })
  })
},

outputは吐き出すRSSのファイル名、titleはフィードのタイトルを指定します。手で設定する場合はこの辺りもすべて設定する必要があります。

苦労には見合わないかもしれない

今回は個人的にRSSリーダーを使っていること、ブログというとだいたいRSSを吐いているというイメージからRSSフィードの生成をやるようにしましたが、今だと更新情報をソーシャルメディアに流したほうが集客には効果的だと思っています。必要な設定量も多く、一般的なブログなどでは苦労に見合わないかもしれませんが、機械が読めるようにすることが重要なWebサイトの構築では今でも必要であることには違いないはずです。