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.
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.