• rss

This blog comes complete with an RSS feed that's generated at build time

This site is built with Next.js. At build time, we use getStaticProps() to fetch the blog post content from Contentful, construct a string of XML, and write it to this XML file in the Next.js public directory, which serves static files.

Looking at the code

The following code can be found in pages/buildrss.js.

1. Fetch all blog posts

import ContentfulApi from "@utils/ContentfulApi";

export default function buildRss(props) {

  return (
    //...
  )
}

export async function getStaticProps() {
  const posts = await ContentfulApi.getAllBlogPosts();

  //...
}

2. Construct the string of XML with blog post data

import ContentfulApi from "@utils/ContentfulApi";

export default function buildRss(props) {

  return (
    //...
  )
}

function buildRssItems(posts) {

  // This is the minimum data required for an RSS feed item

  return posts
    .map((post) => {
      return `
        <item>
          <title>${post.title}</title>
          <description>${post.excerpt}</description>
          <author>${Config.site.email} (${Config.site.owner})</author>
          <link>https://${Config.site.domain}/blog/${post.slug}</link>
          <guid>https://${Config.site.domain}/blog/${post.slug}</guid>
          <pubDate>${post.date}</pubDate>
        </item>
        `;
    })
    .join("");
}

export async function getStaticProps() {
  const posts = await ContentfulApi.getAllBlogPosts();

  const feedString = `<?xml version="1.0"?>
    <rss version="2.0" 
      xmlns:atom="http://www.w3.org/2005/Atom">
      <channel>
        <title>${Config.site.title}</title>
        <link>https://${Config.site.domain}</link>
        <atom:link 
          href="https://${Config.site.domain}/feed.xml" 
          rel="self" 
          type="application/rss+xml" />
        <description>${Config.site.feedDescription}</description>

        ${buildRssItems(posts)}

    </channel>
    </rss>`;

  //...
}

3. Write the string to feed.xml in the public directory

import ContentfulApi from "@utils/ContentfulApi";
import fs from "fs";

export default function buildRss(props) {
  // we can return null here if we don't want to
  // show any content on this page
  return null
}

export async function getStaticProps() {

 //...

 const feedString = ...

  fs.writeFile("./public/feed.xml", feedString, function (err) {
    if (err) {
      console.log("Could not write to feed.xml");
    }

    console.log("feed.xml written to ./public!");
  });

  return {
    props: {
      feedString, // return some data to the page
    },
  };
}

4. Make the RSS feed auto-discoverable

The following code is added to the <head> of each page to allow RSS readers to automatically discover the feed.

<link
  rel="alternate"
  type="application/rss+xml"
  title="RSS Feed"
  href="https://example.com/feed.xml"
 />

And that's it! View your RSS feed at feed.xml.

Alvin Bryan

Developer Advocate at Contentful