External rss feed in your Gridsome site

In this article, we will create a list of last posts from an external Rss feed in a gridsome site.

Add gridsome-source-rss plugin to your gridsome site.

gridsome.config.js

module.exports = {
  
  // [...] general gridsome config

    plugins: [
        {
            use: "gridsome-source-rss",
            options: {
              feedUrl: "https://www.ronjeffries.com/feed.xml",
              typeName: 'RssRonJeffries',
              // Parser options, see: https://www.npmjs.com/package/rss-parser
              // parser: new Parser()
            }
          },
    ],

    // [...] other stuff

In some page or layout, use a GraphQL query to get rss feed data. Note that we use <static-query> because it won't be a query from page component. Also, provide data from this feed to a component we will create just later.

<template>
    <aside>
      <div>Rss feeds I follow</div>
      <RssFeed :feed="$static.rssRonJeffries"></RssFeed>
    </aside>
</template>
<static-query>

query{
    rssRonJeffries: allRssRonJeffries(order: ASC){
        totalCount,
        edges{
            node{id,
            pubDate,
            feedMeta{
                feedUrl,
                title,
                description,
                pubDate,
                link,
                lastBuildDate},
            title,
            link,
            content,
            contentSnippet,
            guid,
            categories,
            isoDate,
            belongsTo{totalCount}
            },
        next{id},
        previous{id}
        }
    }
}

</static-query>


<script>
import RssFeed from "~/components/RssFeed.vue";

export default {
  components: {
    RssFeed
  }
}
</script>

Create a component src/components/RssFeed.vue. It will use GraphQL query result from Rss source defined previously as a param value.

Template

<template>
  <div>
    <div>
      <a :href="rssMeta.link">{{rssMeta.title}}</a>
      - Last post : {{lastPostDate | dateFormatFilter}}
    </div>

    <ul>
      <li v-for="rssItem in rssFeed" :key="rssItem.guid">
        {{rssItem.node.pubDate | dateFormatFilter}} -
        <a
          :href="rssItem.node.link"
        >{{rssItem.node.title}}</a>
      </li>
    </ul>
  </div>
</template>

Script in the component

const isDate = function(date) {
  const timestamp = Date.parse(date);
  return !isNaN(timestamp);
};

const dateFormatFilter = function(value) {
  if (isDate(value)) return new Date(value);
  return value;
};

export default {
  filters: {
    dateFormatFilter(value) {
      if (isDate(value)) {
        const date = new Date(value);
        return (
          ("" + date.getDate()).padStart(2, "0") +
          "/" +
          ("" + (date.getMonth() + 1)).padStart(2, "0") +
          "/" +
          date.getFullYear()
        );
      }
      return value;
    }
  },
  props: ["feed"],
  computed: {
    rssFeed() {
      return this.feed.edges;
    },
    rssMeta() {
      if (this.rssFeed[0].node) {
        return this.rssFeed[0].node.feedMeta;
      }
      return {
        feedUrl: "",
        title: "",
        description: "",
        pubDate: "",
        link: "",
        lastBuildDate: ""
      };
    },
    lastPostDate() {
      if (this.rssFeed[0].node) {
        return this.rssFeed[0].node.pubDate;
      }
      return "";
    }
  }
};