This blog finally has an RSS feed, I welcome you to 1999. When building my own blog instead of using a blogging platform I knew I was getting into a world of pain.
Most of the site is complete and usable, but what lacked was an RSS feed for potential followers to subscribe with! Let’s leave the talk and get-into it!
NPM Dependencies
We’ll have to install a new package aptly named rss for making it easy to generate the RSS feed. Why reinvent the wheel, eh?
yarn add rss @types/rss
note: I added @types/rss
as my next.js project is in typescript
Making A Fake Route
This is probably the point some might have scratched their heads. How can we create a custom dynamic file during build time?
There is no easy way, but this hack works perfectly. Create a new file in pages named something like static_file_build.tsx
(Easter Egg!)
What we will make this route do is,
- Render Dummy Page.
- Load Latest Post Details.
- Write a XML string to a file.
This file serves no display purpose but to ber an entry point to build our rss feed.
import fs from 'fs'
const DummyPage = () => {
return "Dummy Page";
}
const buildRss = (posts: PostEntity[]): string => {
// TODO;
}
export const getStaticProps = async () => {
// Depends On Your Implementation
const posts = PostAPI.getLatest()
// Generate Feed XML
const feedXml = buildRss(posts)
// Write Generated RSS Feed To Public Folder
fs.writeFileSync("public/rss.xml", feedXml);
return {
props: {
posts
},
}
}
export default DummyPage
As shown above, it’s clear how this works. Depending on your backend get your latests posts loaded and let’s get cracking on building the feed!
Building The Feed
Now this is where the installed rss
package comes to the rescue. It has an easy interface/api to build the feed and export the xml. Let’s complete the buildRss function!
Create Feed Object
The first task is to create the feed object. It should be instantiated with your basic site details.
let feed = new RSS({
title: "Kaveen R",
description: "blog posts",
feed_url: `${process.env.BASE_URL}/rss.xml`,
site_url: `${process.env.BASE_URL}`,
pubDate: new Date()
});
Add Posts To Feed Object
Next task is to iterate through all your blog posts and add them to the aforementioned feed object.
// Add Each Post to feed
posts.forEach((post)=>{
// Take Markdown Content & Convert To basic HTML
const body = ReactDOMServer.renderToStaticMarkup(
<ReactMarkdown
escapeHtml={false}
source={post.content}
/>
);
feed.item({
title: post.matter.title,
description: body,
url: `${process.env.BASE_URL}/posts/${post.matter.slug}`,
date: post.matter.date,
category: post.matter.categories,
author: "Kaveen R",
})
})
Important Notes
description
should contain an HTML representation of your blog post content. Buy invoking ReactDOMServer.renderToStaticMarkup()
we’re generating HTML for a given React component. This will change with the libraries you use
categories
is a list of unique strings, when using customizable RSS readers users can filter your latests post using the mentioned catagories.
Serializing The Feed
Last step is to convert the feed object into an XML string which will be written to file by our dummy page!
return feed.xml({indent: true});
Now when building your page you’ll see that feed is generated an place on /public/rss.xml
!
Housekeeping
There are a couple of more things to do! We ant to make sure that our RSS feed is complaint and also can be found by feed readers. This is how to quickly do that
Checking For Feed Errors
To Make Sure we deliver the best RSS feed to all users, we can validate it using a tool such as W3 Validator which will validate and give suggestions on how to make the feed better.
Making Sure The Feed Is Discoverable
On one of your main next.js template(such as _app.ts
) include the following in the header, this meta tag will guide compatible software to the feed.
<Head>
<link
rel="alternate"
type="application/rss+xml"
title="RSS"
href="/rss.xml"
/>
</Head>
Adding rss.xml
to gitignore
This is to anyone who is using GIT VSC. To avoid commiting the RSS file to VCS accidentally add the feed reference to the .gitignore
file.
public/rss.xml
That’s it folks! Now you got a RSS Feed for your blog. It maybe 22 years too late, but at-least we got it!
Complete Code Sample
Here is the complete code sample which we ran through today!
import fs from 'fs'
import RSS from 'rss'
import ReactDOMServer from "react-dom/server";
import ReactMarkdown from "react-markdown";
const DummyPage = () => {
return "Dummy Page";
}
const buildRss = (posts: PostEntity[]): string => {
// Create Feed With Site Details
let feed = new RSS({
title: "Kaveen R",
description: "blog posts",
feed_url: `${process.env.BASE_URL}/rss.xml`,
site_url: `${process.env.BASE_URL}`,
pubDate: new Date()
});
// Add Each Post to feed
posts.forEach((post)=>{
// Take Markdown Content & Convert To basic HTML
const body = ReactDOMServer.renderToStaticMarkup(
<ReactMarkdown
escapeHtml={false}
source={post.content}
/>
);
feed.item({
title: post.matter.title,
description: body,
url: `${process.env.BASE_URL}/posts/${post.matter.slug}`,
date: post.matter.date,
category: post.matter.categories,
author: "Kaveen R",
})
})
// Serialize Feed & Return as string
return feed.xml({indent: true});
}
export const getStaticProps = async () => {
// Depends On Your Implementation
const posts = PostAPI.getLatest()
// Generate Feed XML
const feedXml = buildRss(posts)
// Write Generated RSS Feed To Public Folder
fs.writeFileSync("public/rss.xml", feedXml);
return {
props: {
posts
},
}
}