📖

Hugoでzenn.devのRSSを取り込む

に公開

今日、会社から要望で会社のトップページにzenn.devの記事を取り込めないかという相談がありました。
会社のサイト自体はHugoで実装されているので、RSSから記事を取り込む際に、静的に生成してしまうと最新の情報が表に出ないという問題があります。
というわけで、JavaScriptで動的にRSSを取るような仕組みを作成しました。

弊社のサイトが日本語英語に別れているので、日本語のサイトのみzenn.devのRSSフィードを表示するような仕組みにしました。
まずトップページの_index.ja.mdに以下のようなコードを追加しました。

<div class="container py-3 text-center">
  <div class="row row-cols-1 justify-content-center">
    <div class="col col-lg-10">
      <h2 class="mb-4">Georepublic Tech Blog</h2>
      {{< block/partial item="zenn-dev" >}}
      <div class="pb-5 text-center"><a class="" href="https://zenn.dev/p/georepublic" target="_blank">記事一覧 …</a></div>
    </div>
  </div>
</div>

block/partialではlayouts/partials/components/以下を参照するので、layouts/partials/components/zenn-dev.htmlを作成して、以下のようなコードを組み込みます。

<div id="rss-feed" class="row row-cols-1 row-cols-sm-2 row-cols-md-5"></div>

<script>
  const rss_url = "https://rss2json.com/api.json?rss_url=https://zenn.dev/p/georepublic/feed";

  fetch(rss_url)
    .then(response => response.json())
    .then(data => {
      const feedContainer = document.getElementById('rss-feed');
      const articles = data.items;

      articles.forEach(article => {
        const articleFirst = document.createElement('div');
        articleFirst.className = "col-md-8 offset-md-2 text-start my-2";
        const articleCard = document.createElement('div');
        articleCard.className = "card card-animated shadow-sm border-0 h-100";
        const cardBody = document.createElement('div');
        cardBody.className = "card-body";
        const dateContainer = document.createElement('div');
        dateContainer.className = "text-body-secondary";
        const date = new Date(article.pubDate).toLocaleDateString();
        dateContainer.innerText = date;
        const title = document.createElement('h4');
        title.className = "mb-0";
        title.innerText = article.title;
        const link = document.createElement('a');
        link.href = article.link;
        link.target = "_blank";
        link.className = "stretched-link";
        cardBody.appendChild(dateContainer);
        cardBody.appendChild(title);
        cardBody.appendChild(link);
        articleCard.appendChild(cardBody);
        articleFirst.appendChild(articleCard);
        feedContainer.appendChild(articleFirst);
      });
    })
    .catch(error => console.error('Error fetching RSS feed:', error));
</script>

今回はrss2jsonというサービスを使っています。とりあえず実験的なものなのと、弊社そんなにアクセス来ないだろう(ぉぃ)という魂胆でAPIキーなども取得していないです。
まぁ、トラブルがあったらこっそり教えてください。

Georepublic Tech Blog

Discussion