How to generate an RSS feed with Next.js

Let's learn how to generate an RSS feed for our Next.js website in various formats.

ยท3 min read

In this post, we will show how to generate an RSS feed for your Next.js blog.

The Makerkit SaaS template for Next.js stores much of the configuration within a central file at ~/configuration.ts, thus we will import this file and retrieve all the data we need. In your application, it may be different, so just be sure you get the correct configuration (or write it inline).

Installing the feed package

We're going to install the feed package that helps us write a Feed object:

npm i feed --save-dev

Loading the next.js environment variables programmatically

If you are using environment variables, remember that you need to load them before running the script: to do so, you can manually do it using the function loadEnvConfig from @next/env.

The RSS Feed script

Now, we can finally write the script to create an RSS file with Next.js.

  1. First, we have to fetch all the posts we want to add to the feed: this is going to be wildy different based on your CMS or other approach, so we will simply abstract it with a function named getAllPosts
  2. We load the environment variables from Next.js. This has to be done before loading the configuration.
  3. We retrieve the website configuration from configuration.ts
  4. We iterate over the articles and then we add them to the feed
  5. We write the feed to the public folder in various formats

Below is the full script:

import { Feed } from 'feed'; import { writeFileSync } from 'fs'; import { loadEnvConfig } from '@next/env'; // call {loadEnvConfig} before importing "configuration" to populate the environment variables loadEnvConfig('.'); import Article from './types/post'; import { getAllPosts } from './api'; import configuration from '../../configuration'; const DEFAULT_RSS_PATH = 'public/rss.xml'; const DEFAULT_JSON_PATH = 'public/rss.json'; const DEFAULT_ATOM_PATH = 'public/atom.xml'; const SITE_URL = configuration.site.url; const SITE_DESCRIPTION = configuration.site.description; const SITE_TITLE = configuration.site.name; const SITE_LANGUAGE = configuration.site.language; function generateRSSFeed(articles: Article[]) { const baseUrl = SITE_URL; const author = { email: configuration.site.email, link: configuration.site.twitterHandle, }; const feed = new Feed({ title: SITE_TITLE, description: SITE_DESCRIPTION, id: baseUrl, link: baseUrl, favicon: `${baseUrl}/assets/favicon/favicon.ico`, language: SITE_LANGUAGE ?? `en`, feedLinks: { rss2: `${baseUrl}/rss.xml`, json: `${baseUrl}/rss.json`, atom: `${baseUrl}/atom.xml`, }, author, copyright: '', }); articles.forEach((article) => { // NB: change the below according to your CMS data structure! const { date, slug, title, content, excerpt: description, collection, live, coverImage, } = article; if (!live) { return; } const url = `${baseUrl}/blog/${collection.slug}/${slug}`; feed.addItem({ title, id: url, link: url, description, content, author: [author], date: new Date(date), image: `${baseUrl}${coverImage}`, }); }); writeFileSync(DEFAULT_RSS_PATH, feed.rss2()); writeFileSync(DEFAULT_ATOM_PATH, feed.atom1()); writeFileSync(DEFAULT_JSON_PATH, feed.json1()); } function main() { console.log(`Generating RSS Feed...`); try { generateRSSFeed(getAllPosts()); console.log(`RSS Feed generated successfully...`); process.exit(0); } catch (e) { console.error(`RSS Feed not generated: ${JSON.stringify(e)}`); process.exit(1); } } main();

Generating the RSS Feed at build-time

Now that we have a working script, we want to run the function above after every build. To do so, let's add the following scripts to the package.json file:

"postbuild": "npm run rss", "rss": "npx tsx './rss-feed.ts'",
  1. The rss command used tsx to execute the TS file and generate the RSS files.
  2. The postbuild hook will automatically call the rss command after every build.

That's it! We can now generate an RSS Feed for various formats (json, xml and atom XML) for our Next.js website!