Software Engineer / Product Thinker
← Back

How to create an RSS feed in Nuxt Content

October 3, 2023

Nuxt Content is an amazing tool that makes working with markdown content on Nuxt projects a breeze. Thanks to the power of Nuxt server routes, it's really easy to create an RRS feed.

Let's take a look at the code.

import RSS from "rss";
import { serverQueryContent } from "#content/server";

export default defineEventHandler(async (event) => {
  const BASE_URL = "https://michalkuncio.com";

  const feed = new RSS({
    title: "Blog | Michał Kuncio - Modern webdev - the cool parts",
    site_url: BASE_URL,
    feed_url: `${BASE_URL}/rss.xml`
  });

  const docs = await serverQueryContent(event).sort({ date: -1 }).where({ _partial: false }).find();

  for (const doc of docs) {
    feed.item({
      title: doc.title ?? "-",
      url: `${BASE_URL}${doc._path}`,
      date: doc.date,
      description: doc.description
    });
  }

  const feedString = feed.xml({ indent: true });

  setHeader(event, "content-type", "text/xml");

  return feedString;
});

First of all, let's create a new API route inside api/routes directory by creating a new file called 'rrs.ts'. Thanks to that, the RRS feed will be available on your-domain.com/rrs.xml.

Next, inside our defineEventHandler, we will create a new feed by using the RRS library. Thanks to that library, it will be a little bit easier to parse the RRS feed.

const feed = new RSS({
  title: "Blog | Michał Kuncio - Modern webdev - the cool parts",
  site_url: BASE_URL,
  feed_url: `${BASE_URL}/rss.xml`
});

Next, we have to fetch all the documents we want to include inside our RRS feed. We can make use of serverQueryContent function from '#content/server':

const docs = await serverQueryContent(event).sort({ date: -1 }).where({ _partial: false }).find();

Next up, we have to iterate over our docs and put every one of them to our previously created feed object:

for (const doc of docs) {
  feed.item({
    title: doc.title ?? "-",
    url: `${BASE_URL}${doc._path}`,
    date: doc.date,
    description: doc.description
  });
}

Then, we need an RRS feed string, let's use feed.xml() function for that:

const feedString = feed.xml({ indent: true });

And finally, we have to set the correct response headers for browsers to correctly detect xml file and return our feed string:

setHeader(event, "content-type", "text/xml");

return feedString;

And that's it! I love how easy and clean this solution is. Working with Nuxt Content is really an amazing experience.