Skip to content
  • 🏠 ホーム

  • 📖 記事一覧

  • 🧑‍💻

2020年10月13日

RSS 2.0 対応

ブログでは必要な機能である、RSS の対応をした。(RSSリーダーなどでいろんな記事を購読している人もまだまだ多いハズ。)

XML 生成

RSS フィードに必要な XML を metaデータなどから生成するだけ?で大丈夫。 lastBuildDate に最新の記事の日付を指定することが大事。 仕様 はここ。

// lib/rss.ts

import { Article } from '../interfaces';

const generateRssItem = (article: Article): string => `
  <item>
    <guid>https://7kaji.page/articles/${article.slug}</guid>
    <title>${article.meta.title}</title>
    <link>https://7kaji.page/articles/${article.slug}</link>
    <description>${article.meta.description}</description>
    <pubDate>${new Date(article.meta.date).toString()}</pubDate>
  </item>
`;

const generateRss = (articles: Article[]): string => `
  <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
      <title>7kaji.page | 記事一覧</title>
      <link>https://7kaji.page/articles</link>
      <description>いろいろ書いていきます。</description>
      <language>ja</language>
      <lastBuildDate>${new Date(articles[0].meta.date).toString()}</lastBuildDate>
      <atom:link href="https://7kaji.page/rss.xml" rel="self" type="application/rss+xml"/>
      ${articles.map(generateRssItem).join('')}
    </channel>
  </rss>
`;

export default generateRss;

記事一覧ページの getStaticProps でこの処理を行うので、build 時に静的なファイルとして xml ファイルを生成することができる。便利。

// pages/articles/index.tsx

import fs from 'fs';
import generateRss from '../../lib/rss';
import { getAllDocs } from '../../lib/doc';
import { ArticlesProps } from '../../interfaces';
import Layout from '../../components/Layout';
import Articles from '../../components/Articles';

export default function Docs(props: ArticlesProps) {
  const meta = {
    title: "記事一覧",
    description: '記事一覧です。'
  }
  return (
    <Layout meta={meta}>
      <h1>記事一覧</h1>
      <Articles articles={props.articles} />
    </Layout>
  );
}

export async function getStaticProps() {
  const docs = getAllDocs().reverse();

  // RSS 対応したのは👇だけ
  const rss = generateRss(docs);
  fs.writeFileSync('./public/rss.xml', rss);

  const articles = docs.map(doc => {
    return { slug: doc.slug, title: doc.meta.title }
  });
  return {
    props: {
      articles,
    }
  };
}

pages/_document.tsx に必要なヘッダーを設定することも忘れずに

// pages/_document.tsx

      <Html lang="ja">
        <Head>
          <link
            rel="alternate"
            type="application/rss+xml"
            title="RSS feed for blog posts"
            href="https://7kaji.page/rss.xml"
          />
        </Head>

ちな

自分は Mac のアプリの Reeder というものを使ってるんだけど、公式のサイトをみたら 新しいバージョン がもうすぐ出そうな気配がしてた。