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>${shortSiteDescription}</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.
Top comments (2)
Thanks for the post. For those looking, you can validate the RSS feed generate here: validator.w3.org/feed/
Thanks for the post, Fredrik.
Can I request to highlight code snippets (it'd help making it more readable 🙂)?
You can refer to the Editor Guide for more info.