iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
📰

Generating a Dynamic RSS Feed in Next.js

に公開
3

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

pages/feed.tsx
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

わたるわたる

とても参考になる記事有難うございます!

本当に些細な箇所ですが、一連の流れ的に

feed.xml();

return feed.xml();になりそうです。

catnosecatnose

あっ…、ありがとうございます!修正しました。