A drawn image of Fredrik Bergqvist in a blue shirt

Fredrik Bergqvist

Web developer with over 22 years of experience. Writing about javascript and front end techniques

How to add an RSS-feed to your Next.js site

I love RSS-feeds (and still curse Google for cancelling Google Reader) and use them as my main news source for things I find interesting so with this article I would like to help people to add RSS-feeds to their blogs.

If you read my article about how to add a sitemap.xml to your next.js site you will recognise much of the code, it's pretty much the same base but with slightly different XML-markup.

Creating the page

First off we need a page that can return the XML. I suggest you name it "rss", "feed" or something similar.

In getInitialProps we get our blog posts and set the "Content-Type"-header to "text/xml" so the browser knows that should expect XML instead of HTML.
We then generate the XML and passes it on to the browser using res.write.

export default class Rss extends React.Component {
  static async getInitialProps({ res }: NextPageContext) {
    if (!res) {
      return;
    }
    const blogPosts = getRssBlogPosts();
    res.setHeader("Content-Type", "text/xml");
    res.write(getRssXml(blogPosts));
    res.end();
  }
}

Generating the base XML for the feed

For the base XML document you will need to add some basic information like the title of the log, a short description, link to your website and the language of the content.
Title, link and description are mandatory elements in the RSS specification but add as many optional elements as you find useful.

const getRssXml = (blogPosts: IBlogPost[]) => {
  const { rssItemsXml, latestPostDate } = blogPostsRssXml(blogPosts);
  return `<?xml version="1.0" ?>
  <rss version="2.0">
    <channel>
        <title>Blog by Fredrik Bergqvist</title>
        <link>https://www.bergqvist.it</link>
        <description>Web developer with over 22 years of experience. Writing about javascript and front end techniques</description>
        <language>en</language>
        <lastBuildDate>${latestPostDate}</lastBuildDate>
        ${rssItemsXml}
    </channel>
  </rss>`;
};

Adding XML for the blog items

With the basic stuff out of the way all we need to go is generate some XML for the blog posts and figure out when the blog was updated.

The item element should at least contain a link to the blog post, the date when it was published and the text. You can either opt to put a short description and force the user to come visit your page or put the whole post in the XML.

If you have HTML-markup in your text you need to enclose it within a <![CDATA[${ post.text }]]>-tag or HTML encode the text.

const blogPostsRssXml = (blogPosts: IBlogPost[]) => {
  let latestPostDate: string = "";
  let rssItemsXml = "";
  blogPosts.forEach(post => {
    const postDate = Date.parse(post.createdAt);
    if (!latestPostDate || postDate > Date.parse(latestPostDate)) {
      latestPostDate = post.createdAt;
    }
    rssItemsXml += `
      <item>
        <title>${post.title}</title>
        <link>
          ${post.href}
        </link>

        <pubDate>${post.createdAt}</pubDate>
        <description>
        <![CDATA[${post.text}]]>
        </description>
    </item>`;
  });
  return {
    rssItemsXml,
    latestPostDate
  };
};

Finishing up

The last thing you need to do is to add a link to your feed somewhere in the head of your document.

<link 
  rel="alternate" 
  type="application/rss+xml" 
  title="RSS for blog posts" 
  href="https://www.bergqvist.it/rss" />

This will make it easier for browsers and plugins to auto discover your feed.

The code is available as a gist on github and please leave a comment with any feedback.