LoginSignup
0
0

サイト

リポジトリ

方針

実装

  • rss.tsファイルにRSSフィード生成のためのコードを実装します。
    • 外からimportしているsortFunctionDESCRIPTION等の定数については、ここでは割愛します。

rss.ts

import fs from 'fs';
import type { Post } from './.contentlayer/generated';
import { sortFunction } from './src/lib/utils';
import { DESCRIPTION, TITLE, URL_BASE } from './src/lib/const';

const generateRss = (allPosts: Post[]) => {
  const path = './public/rss.xml'
  const items = allPosts.sort(sortFunction).splice(0, 10).map(post => {
    return `<item>
<guid>${URL_BASE}${post.url}</guid>
<title>${post.title}</title>
<description>${post.description}</description>
<link>${URL_BASE}${post.url}</link>
<pubDate>${new Date(post.date).toUTCString()}</pubDate>
</item>`
  })

  const rss = `<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>${TITLE}</title>
<link>${URL_BASE}</link>
<description>${DESCRIPTION}</description>
<atom:link href="${URL_BASE}/rss.xml" rel="self" type="application/rss+xml" />
${items.join('')}
</channel>
</rss>`
  fs.writeFileSync(path, rss)
}

export default generateRss;

  • 見ての通りで、Contentlayerで生成したドキュメントから最新の記事10件を取り出し、テンプレートリテラルでひたすら埋め込みます。

contentlayer.config.ts

  • ContentlayerのmakeSourceの引数に渡すオブジェクトに、onSuccessを生やして関数を入れておくと、ドキュメントのビルド成功時に実行してくれます。
import { makeSource } from 'contentlayer/source-files';
import generateRss from "./rss";

/* ... 中略 ... */

export default makeSource({
  contentDirPath: 'posts',
  documentTypes: [Post],
  markdown: {
    //@ts-expect-error
    remarkPlugins: [remarkDirective, remarkDirectiveRehype, remarkGfm],
    rehypePlugins: [
      rehypeSlug,
      [rehypeAutolinkHeadings, { behavior: 'append' }],
      [rehypePrettyCode, { ...prettyCodeOptions }],
    ],
  },
  onSuccess: (async (importData) => {
    // generate rss feed
    const { allPosts } = await importData()
    generateRss(allPosts);
  })
});

出来るもの

  • ./public/rss.xmlにこのような感じでファイルが生えます。
    • W3CのFeed Validatorに投げたらThis is a valid RSS feed.と出たので、大丈夫なはず。
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title>Crumbs on the table</title>
<link>https://kedama-t.netlify.app</link>
<description>技術・思考・読書のメモブログ</description>
<atom:link href="https://kedama-t.netlify.app/rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://kedama-t.netlify.app/posts/tech/01.create_own_blog</guid>
<title>ブログの構築</title>
<description>Next.js + Tailwind CSS + Contentlayer で自分だけのMarkdownブログを作る</description>
<link>https://kedama-t.netlify.app/posts/tech/01.create_own_blog</link>
<pubDate>Fri, 01 Dec 2023 00:00:00 GMT</pubDate>
</item>
<item>
<guid>https://kedama-t.netlify.app/posts/idea/01.remark_memo</guid>
<title>remarkについてのメモ</title>
<description>undefined</description>
<link>https://kedama-t.netlify.app/posts/idea/01.remark_memo</link>
<pubDate>Thu, 30 Nov 2023 00:00:00 GMT</pubDate>
</item>
<item>
<guid>https://kedama-t.netlify.app/posts/booklog/01.booklog</guid>
<title>積本状況 in 202311</title>
<description>あるいはブラックフライデーの戦利品</description>
<link>https://kedama-t.netlify.app/posts/booklog/01.booklog</link>
<pubDate>Tue, 28 Nov 2023 00:00:00 GMT</pubDate>
</item>
<item>
<guid>https://kedama-t.netlify.app/posts/tech/02.app_idea_in_202311</guid>
<title>作りたいもの in 202311</title>
<description>いつか作るかもしれないもの</description>
<link>https://kedama-t.netlify.app/posts/tech/02.app_idea_in_202311</link>
<pubDate>Tue, 28 Nov 2023 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>

終わりに

  • Contentlayer、かゆいところに手が届いていいですね。
  • RSSってあんまり今時じゃないかもしれないですが、使うと案外便利ですよね。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0