Your Next.js blog can benefit from providing an RSS feed. In this article, I'll discuss what RSS is, why you should provide it, and most importantly, how to build an RSS feed with Next.js.
What is RSS?
RSS is an acronym for Really Simple Syndication and is a Web content syndication format. You can read the RSS specification for all of the details.
Why Should I Provide an RSS Feed for My Blog?
Providing an RSS feed will allow your readers to subscribe to your blog updates with their browsers or dedicated RSS Readers.
But the RSS feed benefits don't stop with subscribers.
I previously discussed canonical links and cross-posting to popular blog sites like DEV and Hashnode. Both of those sites allow you to provide your RSS feed as a way to import your articles.
Google will also accept an RSS feed as a sitemap. However, I recommend a separate sitemap, and I previously discussed how to build a sitemap with Next.js.
How to Build an RSS Feed with Next.js
Next.js does not offer built-in support for creating an RSS feed as of this writing (November, 2023), but it would not surprise me if it is provided in the future. After all, Next.js already provides built-in sitemap generation support as of version 13.3.
No worries, you can build an RSS feed in Next.js on your own.
RSS dependency
Start by adding the rss
dependency to your project by typing the following in your terminal:
npm i rss
You should now see it listed under dependencies
in your package.json
file.
Static Route Handler
You need to create a static route handler in Next.js.
Inside your app
directory, create a new folder. You can name the folder feed.xml
, webfeed.xml
or channel.xml
if you want to stick with standard naming conventions. It must end with .xml
. This will be the name of the file you generate for your RSS feed.
Now you need to create a route.ts
file inside of your folder.
Here is what your route.ts
file should look like to start:
import RSS from "rss"
export async function GET() {
return new Response('', {
headers: {
'Content-Type': 'application/xml; charset=utf-8',
},
});
}
Create an RSS Instance
Next, you need to create a new RSS instance and provide it with details about your RSS feed. You can find field descriptions on the npm page for rss. I also cross-referenced the RSS specification as I created mine.
Here it is:
import RSS from "rss"
export async function GET() {
const feed = new RSS({
title: 'Dave Gray Teaches Code',
description: "Dave Gray's Blog",
generator: 'RSS for Node and Next.js',
feed_url: 'https://www.davegray.codes/feed.xml',
site_url: 'https://www.davegray.codes/',
managingEditor: 'dave@davegray.codes (Dave Gray)',
webMaster: 'dave@davegray.codes (Dave Gray)',
copyright: `Copyright ${new Date().getFullYear().toString()}, Dave Gray`,
language: 'en-US',
pubDate: new Date().toUTCString(),
ttl: 60,
});
return new Response('', {
headers: {
'Content-Type': 'application/xml; charset=utf-8',
},
});
}
Note: the ttl value should be an integer. An incorrect example value is given on the npm page.
Add Feed Items
Finally, you will need to bring in your individual page data like I do with my getPostsMeta
function. This will allow you to populate the individual items of the feed. In my example below, I map over my blog posts and create a new feed.item
for each:
import RSS from "rss"
import { getPostsMeta } from "@/lib/posts"
export async function GET() {
const feed = new RSS({
title: 'Dave Gray Teaches Code',
description: "Dave Gray's Blog",
generator: 'RSS for Node and Next.js',
feed_url: 'https://www.davegray.codes/feed.xml',
site_url: 'https://www.davegray.codes/',
managingEditor: 'dave@davegray.codes (Dave Gray)',
webMaster: 'dave@davegray.codes (Dave Gray)',
copyright: `Copyright ${new Date().getFullYear().toString()}, Dave Gray`,
language: 'en-US',
pubDate: new Date().toUTCString(),
ttl: 60,
});
const allPosts = await getPostsMeta()
if (allPosts) {
allPosts.map((post) => {
feed.item({
title: post.title,
description: post.description,
url: `https://www.davegray.codes/posts/${post.id}`,
categories: post.tags || [],
author: "Dave Gray",
date: post.date,
});
});
}
return new Response(feed.xml({ indent: true }), {
headers: {
'Content-Type': 'application/xml; charset=utf-8',
},
});
}
Update the Response
Notice I updated the Response
above to include feed.xml({ indent: true })
instead of the open quotes from the earlier examples. The xml
method returns the feed
created above. The indent
value provides what to use as a tab. You can read more about the indent setting.
The Output
It's important to note that the Next.js docs state static route handlers "will render a static response when running next build
". Therefore, when you deploy your site and the build process runs, your feed.xml
file will be created.
However, you can preview your feed.xml
file in dev mode.
Type npm run dev
in your terminal to launch your Next.js project. Then visit localhost:3000/feed.xml
in your browser to see the final output.
You can also use the W3C Feed Validation Service to validate your feed format.
Special Thanks
I'd like to give a tip of the hat to Colby Fayock for writing an excellent article on creating an RSS feed earlier this year. I referenced his article along with the other resources linked above as I created my own RSS feed.