Blog

Creating a Feed for a Git-based CMS with Nuxt

Since I'm currently using Netlify CMS for my blog, I wanted to create a RSS feed for it even if their usage may be statistically down. The site is statically generated using Nuxt, so in doing further research on anything out there that creates a feed, I found Feed module - Everyone deserves RSS, Atom and Json.

I've already followed the guide on setting up Netlify CMS with Nuxt, so this guide will be geared slightly toward that setup and configuration. Netlify CMS is configured to save blog posts in /assets/content/blog/ in .json files. However, the example given in the Configuration of the Feed create function of the feed-module is based on a JSON collection of posts from an API. This data for the feed create function can be easily be retrieved using an API set up to deliver it (e.g. Contentful API), but how do you get this data from a directory of files created by a Git-based CMS?

Getting all posts based off of files in a directory

This can be done some work in nuxt.config.js which will be used when the generate command is used which will ultimately create the feed.xml file. In this file, make sure you include these three dependencies that will be needed:

const fs = require('fs');
const glob = require('glob');
const path = require('path');

glob will search for and match the blog posts files, path will help resolve the paths and related references, and fs will allow these files to be parsed so that their data can be used to create the feed. Here is the code in nuxt.config.js that I used:

let dynamicRoutes = [];
let globSearchResults = glob.sync('*.json', { cwd: 'assets/content/blog' });
let posts = [];

globSearchResults.forEach(file => {
  fs.readFile(path.resolve('assets/content/blog', file), 'utf8', function(err, data) {
    if (err) {
      console.log(err);
    }
    else {
      let post = JSON.parse(data);
      post.url = 'https://jeremywynn.com/blog/' + path.parse(file).name;
      posts.push(post);
    }
  });
  let dynamicRoute = '/blog/' + path.parse(file).name;
  dynamicRoutes.push(dynamicRoute);
});

Each .json file has 4 properties: title, date, description, and body. When each file is found by glob, fs will parse its contents (using JSON.parse()) where it will be assigned to a variable that is pushed to the posts array which is set up to collect all the posts.

Note: The dynamicRoutes bit is where I refactored the code under the Generating pages with the generate property section of the Netlify CMS for Nuxt Doc. Since the globbing is already being done above, entries for dynamicRoutes can be made and pushed here, and then the generate method in Nuxt can be reduced to this:

generate: {
  routes: dynamicRoutes
},

Giving data and configuring the Nuxt Feed module

Now the data in the posts array is ready for the feed create function portion for the feed part in nuxt.config.js:

feed: [
  {
    path: '/feed.xml',
    async create(feed, data) {
      feed.options = {
        title: 'Title goes here',
        link: 'URL goes here',
        description: 'Description goes here'
      }
      data.forEach(post => {
        feed.addItem({
          title: post.title,
          id: post.url,
          link: post.url,
          date: new Date(post.date),
          description: post.description,
          content: post.body
        })
      })
    },
    cacheTime: 1000 * 60 * 15,
    type: 'rss2',
    data: posts
  }
],

The data property is assigned to the posts array that was populated earlier. Since post.date is merely a string representing a date, it will need to be converted to a Date object, or the feed module will throw an error.

Don't forget to include @nuxtjs/feed in the array of modules in nuxt.config.js:

modules: [
  '@nuxtjs/feed',
  '@nuxtjs/robots'
],

If you wish to place a link to this feed in your head, add this to your link array in nuxt.config.js:

{ rel: "alternate", type: "application/rss+xml", title: "Your Title", href: "https://yoursite.com/yourfeed.xyz" }

In the end, you'll end up with a feed like this. This file will only be created when nuxt generate is run. When hosting on a service like Netlify, you can set this command to automatically run each and every time you create a blog post in a Git-based CMS since it updates the Git repository that comprises your site.