DEV Community

Rafael Magalhaes
Rafael Magalhaes

Posted on • Originally published at blog.rrrm.co.uk on

Create an RSS feed with Nuxt 3

What is RSS?

An RSS feed is a structured file format used to publish frequently updated content such as blog posts, news articles, and podcasts. It allows readers to easily access and subscribe to new content without having to visit the website directly. RSS feeds are important because they save time and provide a convenient way to keep up-to-date with multiple sources of information from a single platform. They are commonly used by publishers, bloggers, and news outlets to distribute content to their audiences.

Benefits of having RSS feed

Creating an RSS feed for your website can provide several benefits, including:

  1. Convenience: RSS feeds allow readers to easily access and stay updated on multiple sources of content in one place without having to visit each website individually. This saves time and provides a more convenient user experience.
  2. Increased engagement: RSS can help increase engagement with your audience by allowing readers to share your content on social media or other platforms easily. This can lead to more traffic and greater visibility for your website.
  3. Search engine optimization: RSS feeds can help improve your website's search engine rankings by providing a steady stream of fresh, relevant content. This can help increase your website's visibility and drive more traffic to your site.

Setting up a Nuxt 3 project

In this tutorial I will show you how to generate an RSS feed in nuxt 3 using server routes, this should provide a good insight on how the new server feature in nuxt 3 works with nitro

lest create a new project

npx nuxi init nuxt3-rss

cd into nuxt3-rss install depencies, we also need to add the rss package

npm i rss && npm i -D @types/rss

Creating a server route for your RSS feed

Nuxt 3 is powered by a new server engine, Nitro.

the server directory works like the page directory with a file-based routing system for your API routes

Nuxt automatically scans files inside the ~/server/api, ~/server/routes, and ~/server/middleware directories to register API and server handlers with HMR support.

server/
  api/         
    test.ts    <-- /api/test
  hello.ts     <-- /hello
Enter fullscreen mode Exit fullscreen mode

for this tutorial, we are going to focus on the server routes instead of the API

Files inside the ~/server/api are automatically prefixed with /api in their route. For adding server routes without /api prefix, you can instead put them into ~/server/routes directory.

for example

// server/routes/hello.ts
export default defineEventHandler(() => 'Hello World!')
Enter fullscreen mode Exit fullscreen mode

Given the example above, the /hello route will be accessible at http://localhost:3000/hello.

We need to create a server directory at the root of the project and a routes folder inside server directory

mkdir server
cd server
mkdir routes
Enter fullscreen mode Exit fullscreen mode

inside server/routes create rss.ts file

// server/routes/rss.ts
export default defineEventHandler(() => 'RSS page!')
Enter fullscreen mode Exit fullscreen mode

navigate to http://localhost:3000/rss and make sure everything is working

here's an RSS example that we are going to try dynamically render

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>My Website</title>
    <link>http://www.example.com/</link>
    <description>My website's RSS feed</description>
    <lastBuildDate>Tue, 22 Feb 2023 12:00:00 GMT</lastBuildDate>
    <item>
      <title>Article Title</title>
      <link>http://www.example.com/article1</link>
      <description>This is the first article on my website.</description>
      <pubDate>Tue, 21 Feb 2023 12:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Another Article Title</title>
      <link>http://www.example.com/article2</link>
      <description>This is the second article on my website.</description>
      <pubDate>Mon, 20 Feb 2023 12:00:00 GMT</pubDate>
    </item>
  </channel>
</rss>
Enter fullscreen mode Exit fullscreen mode

In this example, the rss tag specifies the version of the RSS format used (in this case, version 2.0). The channel tag contains information about the RSS feed, such as the website's title, description, and link. Each item tag represents an individual article in the feed, with a title, link, description, and publication date.

Our object is to fetch a list of items from an API, loop over each article and include them in the item tag in our RSS fed

I'm going to make use of dev.to API to get a list of my arctiles


// server/routes/rss.ts

import RSS from 'rss';

export default defineEventHandler(async (event) => {
  // wrap everything in a try catch block
  try {
    // fetch data from dev.to
    const response = await fetch(
      'https://dev.to/search/feed_content?per_page=15&page=0&user_id=138553&class_name=Article&sort_by=published_at&sort_direction=desc&approved='
    );

    // throw an error if the response is not ok
    if (!response.ok) {
      throw new Error(response?.status);
    }

    /*
      await for response.json()
      the api returns an object with the result key and result contains all our articles inside an array
      assign result to posts
     */
    const {result:posts} = await response.json();

    // create new rss feed this will be our channel tag with website title and url
    const feed = new RSS({
      title: 'Rafael Magalhaes',
      site_url: 'https://dev.to/rafaelmagalhaes', // link to your website/blog
      feed_url: `https://blog.rrrm.co.uk/rss`, // path to your rss feed
    });
    // loop over each posts
    for (const post of posts) {
      // add item tag to our rss feed with correct data
      feed.item({
        title: post.title, // title from post to item title
        url: `https://dev.to/${post.path}`, // full path to where our article is hosted
        //description: '', // dev.to APIs doesn't return a description, if you have one you can add it here
        date: post.published_at_int, // date post was created
        categories: post.tag_list, // list of tags
      });
    }
    const feedString = feed.xml({ indent: true }); //This returns the XML as a string.

    event.node.res.setHeader('content-type', 'text/xml'); // we need to tell nitro to return this as a xml file
    event.node.res.end(feedString); // send the HTTP response
  } catch (e) {
    // return an error
    return e;
  }
});

Enter fullscreen mode Exit fullscreen mode

Now if we navigate to http://localhost:3000/rss It should return an xml file with a list of our articles

you can find the repository here: https://github.com/rafaelmagalhaes/nuxt3-rss

Top comments (0)