How to create an RSS feed in Nuxt Content

Created by human

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.

© Copyright 2024 Michał Kuncio