iTranslated by AI
Generating a Dynamic RSS Feed in Next.js
Recently, I wrote about how to generate an XML Sitemap with Next.js. Since RSS feeds can be implemented using the same approach, I'm documenting it here.
Dynamically Generating an RSS Feed with getServerSideProps in Next.js
We will implement this within a Next.js (TypeScript) Page component. For example, let's create a file named /pages/feed.tsx so that the RSS feed is displayed when accessing /feed.
Why use getServerSideProps?
In this sample, we handle everything from generating the RSS data to returning the response inside getServerSideProps. While getServerSideProps is originally intended for fetching props to be used within a Page component, here we return the response directly without going through the Page component.
This is because if you were to return HTML or XML within the Page component, it would be embedded inside _app.tsx or _document.tsx, resulting in unnecessary elements like layouts and meta tags being mixed in.
Sample Code
import { GetServerSidePropsContext } from 'next';
export const getServerSideProps = async ({ res }: GetServerSidePropsContext) => {
const xml = await generateFeedXml(); // Generate the feed XML (to be discussed later)
res.statusCode = 200;
res.setHeader('Cache-Control', 's-maxage=86400, stale-while-revalidate'); // Cache for 24 hours
res.setHeader('Content-Type', 'text/xml');
res.end(xml);
return {
props: {},
};
};
const Page = () => null;
export default Page;
Since you can receive res as an argument in getServerSideProps, you can return the response in the form of res.end(RSS feed content) after adding Content-Type and Cache-Control to the header.
Generating the RSS Feed
Next is the generation of the RSS feed itself; here, we will use an npm library called rss.
$ npm install rss
$ npm install --save-dev @types/rss
import RSS from 'rss';
async function generateFeedXml() {
const feed = new RSS({
title: "Title",
description: "Description",
site_url: "Site URL",
feed_url: "Feed page URL",
language: 'ja',
});
// Example of including posts
// Please refer to the library documentation for details on how to write this
const { posts } = await getPosts();
posts?.forEach((post) => {
feed.item({
title: post.title,
description: post.description,
date: new Date(post.createdAt),
url: `${Site URL}/${post.path}`,
});
})
// Convert to XML string format
return feed.xml();
}
Simply call this from the getServerSideProps mentioned earlier, and you're done. It's a good idea to check whether the generated RSS is in the correct format using something like the W3C Feed Validation Service.
Discussion
とても参考になる記事有難うございます!
本当に些細な箇所ですが、一連の流れ的に
は
return feed.xml();になりそうです。あっ…、ありがとうございます!修正しました。
お手数おかけしました!有難うございます!