How to Add an RSS Feed to Your Gatsby Site
January 30th, 2021
(15-minute read)
Introduction
As a content creator, you want to make it easy for your readers to stay updated on your latest content. By adding an RSS feed to your site, readers can get automatic updates whenever you post a new article, video, or photo of your dog.
In this post, I'll show you how to add an RSS feed to a Gatsby site.
A Quick Crash Course on RSS Feeds
How does an RSS feed work?
RSS stands for "really simple syndication." In other words, it's a way to give other websites information about your content so that they can get it in front of more users.
Here's a brief overview of how it works:
- Your site generates an RSS feed that includes information about all your content. You add a link to it someplace (maybe your site's header or footer) where it's easy for users to find.
- A reader decides they love your content and want to get updates from your site. (Hooray!) They add the URL for your RSS feed to whatever feed aggregator software they use (like Feedly). The feed aggregator periodically checks your RSS feed to see if there's any new content.
- Time goes by. When you post a new piece of content, your RSS feed gets updated to include additional data about the new content.
- The next time your reader's feed aggregator checks your site's RSS feed, it sees the new content and notifies the reader. The reader checks out your new content and marvels at how handy it is that your site has an RSS feed!
The best part: once you set up your RSS feed the first time, all the updates happen automatically! 🥳
What does an RSS feed actually look like?
An RSS feed is a specific kind of XML file. The structure looks similar to HTML, but it uses different kinds of elements.
The two main RSS elements are:
<channel>
- Contains information about your overall site, like the URL where it's hosted. Each RSS feed contains a single<channel>
element, which itself contains one or more<item>
child elements.<item>
- Contains information about a single unit of content on your site, like a specific blog post or video. You'll have multiple<item>
elements - one for each piece of content on your site.
Prerequisites
In this post, you'll learn specifically how to add an RSS feed to an existing Gatsby site.
If you don't have a Gatsby site of your own, that's fine! I created some starter code that you can use to follow along. (Don't worry, I won't tell.) More on that in the next section.
If you'd rather follow along with your own Gatsby site, it will be helpful to have a basic blog set up, with separate pages for each post. The starter code uses the gatsby-transformer-remark
plugin to query for Markdown nodes, but if your blog posts use something besides Markdown, you can make adjustments to the GraphQL queries specified in this post.
The Starter Code
The starter code for this post is a simplified Gatsby blog. Posts are written in Markdown and are stored in the src/blog
directory.
To get the site up and running locally:
- Fork the starter project repo on GitHub.
- Clone your forked repo. (Don't forget to swap out
<your-github-username>
for your own GitHub username.)shellgit clone https://github.com/<your-github-username>/gatsby-blog-with-rss-feed-example.git
- In your terminal, change directories into the repo you just cloned.
shell
cd gatsby-blog-with-rss-feed-example
- Start up the local development server.
shell
npm run develop
- In a web browser, navigate to
localhost:8000
. You should see something like this:
Adding an RSS Feed
The high-level process for adding an RSS feed to your Gatsby site looks like this:
- Prerequisite: Confirm that you have
siteMetadata
set up in yourgatsby-config.js
file. - Step 1: Install the
gatsby-plugin-feed
plugin. - Step 2: Configure
gatsby-plugin-feed
in yourgatsby-config.js
file. - Step 3: Build and serve your site locally to test the RSS feed.
- Step 4: (Optional) Add a link to your RSS feed to your site.
Prerequisite: Confirm that you have siteMetadata
If you haven't already, you'll need to add a siteMetadata
object to your gatsby-config.js
file. This object contains high-level information about your site.
Your siteMetadata
object will need the following properties:
title
- The name of your site.siteUrl
- The URL where your site will be hosted once it's deployed.description
- A short sentence describing the purpose of your site.
This data will be added to the <channel>
element in your RSS feed.
The starter code shows what this looks like in context:
module.exports = {
siteMetadata: {
title: "My Personal Blog",
siteUrl: "https://my-personal-blog.com",
description:
"An example Gatsby blog with an automatically generated RSS feed.",
},
// ...
}
Step 1: Install gatsby-plugin-feed
In your command line, install gatsby-plugin-feed
.
npm install gatsby-plugin-feed
This will add the plugin to your package.json
file as a dependency and add it to your node_modules
folder.
Step 2: Configure the plugin in your gatsby-config.js
file
To make your Gatsby site actually use the plugin, you need to add it to the plugins
array in your gatsby-config.js
file. (You can add it before or after the existing plugins; it doesn't matter.)
module.exports = {
siteMetadata: { /* ... */ },
plugins: [
{
resolve: 'gatsby-plugin-feed',
options: {
// We'll get to this in a moment
}
},
// The rest of the existing plugins
]
}
Next, configure the additional options that gatsby-plugin-feed
needs to generate your RSS feed. Your options
object should have the following fields:
query
- The GraphQL query for pulling in data that should be shared across all the RSS feeds generated.- By default, this will pull in the data from
siteMetadata
. It's still a good idea to configure the query yourself, so that it's explicit.
- By default, this will pull in the data from
feeds
- An array of feed objects (described below).- Unless you want to have separate RSS feeds for different kinds of content, you'll probably only need one feed object in this array.
A feed object has the following properties:
title
- (string) The text to put in the<title>
element of the generated RSS feed.output
- (string) The path where you want your generated RSS feed to be hosted on your site.query
- (string) A GraphQL query for how to get the data for the contents of the feed.serialize
- (function) A function specifying how to set properties on the<item>
elements in the RSS feed for each piece of content.
Setting the title
and output
options are more straightforward, but the query
and serialize
options are described in more detail below.
Configuring options.query
and feed.query
You may have noticed that there are two different query
attributes in the plugin configuration: one under options
and one in an individual feed object. Why are there two?
Imagine if you wanted to generate multiple RSS feeds for your site. For example, maybe you want one RSS feed for your blog posts and a separate RSS feed for your videos. Some of the data for your RSS feed will be the same in both cases (like the metadata for your site), but other data will be different (like the content of each <item>
element in your feed).
The data from options.query
will be included in all of your RSS feeds, while the data from the query
field on a feed object will only be used for that specific feed.
Now let's put this into practice!
The query to pull in your shared site metadata will look like this:
`
{
site {
siteMetadata {
title
description
siteUrl
site_url: siteUrl
}
}
}
`
And the query to pull in your blog data for your feed will look like this:
`
{
allMarkdownRemark(sort: {fields: frontmatter___date, order: ASC}) {
nodes {
frontmatter {
title
date
description
}
html
slug: gatsbyPath(filePath: "/{MarkdownRemark.frontmatter__title}")
}
}
}
`
Configuring serialize
The serialize
option takes a function that shows how to use the data from your GraphQL queries to build up the fields in each <item>
element in the feed.
For this project, your serialize
function will set the following properties for each item:
title
- The name of this piece of content.description
- (optional) A 1-2 sentence summary of this piece of content.url
- The full URL where this piece of content lives.- This will show up as a
<link>
element in the<item>
element generated for the RSS feed.
- This will show up as a
guid
- Globally unique identifier. A string that is unique to this piece of content. (You can just use the URL again for this.)date
- The publish date for this piece of content.- This will show up as a
<pubDate>
element in the<item>
element generated for the RSS feed.
- This will show up as a
serialize
receives all the data from the combined options.query
and feed.query
response. You can destructure this data and use it in your configuration for each <item>
element. For example, the function below will create an <item>
element with the title
, description
, and date
data from node.frontmatter
, and it also adds a url
and guid
property by combining data from the site
and allMarkdownRemark
queries.
({ query: { site, allMarkdownRemark } }) => {
return allMarkdownRemark.nodes.map(node => {
return Object.assign({}, node.frontmatter, {
url: `${site.siteMetadata.siteUrl}${node.slug}`,
guid: `${site.siteMetadata.siteUrl}${node.slug}`,
})
})
}
The Full Plugin Configuration
After adding all the plugin options to your gatsby-config.js
file, the configuration for gatsby-plugin-feed
should look like this:
{
resolve: "gatsby-plugin-feed",
options: {
query: `
{
site {
siteMetadata {
title
description
siteUrl
site_url: siteUrl
}
}
}
`,
feeds: [
{
title: "My Personal Blog RSS Feed",
output: "rss.xml",
query: `
{
allMarkdownRemark(sort: {fields: frontmatter___date, order: ASC}) {
nodes {
frontmatter {
title
date
description
}
html
slug: gatsbyPath(filePath: "/{MarkdownRemark.frontmatter__title}")
}
}
}
`,
serialize: ({ query: { site, allMarkdownRemark } }) => {
return allMarkdownRemark.nodes.map(node => {
return Object.assign({}, node.frontmatter, {
url: `${site.siteMetadata.siteUrl}${node.slug}`,
guid: `${site.siteMetadata.siteUrl}${node.slug}`,
})
})
},
}
]
}
},
Step 3: Build and serve your site locally to test the RSS feed
gatsby-plugin-feed
only generates an RSS feed for production-style builds. (In other words, the URL to your RSS feed won't work if you're running npm run develop
. You'll get a 404 error.)
To test your RSS feed locally, you'll have to build your site and start up a server by running the following command:
npm run build && npm run serve
Once your site is up and running, you should be able to see it in a web browser at localhost:9000
. You can check your RSS feed by visiting localhost:9000/rss.xml
(or whatever you configured the output
option to be).
The generated RSS feed should look something like this:
<rss version="2.0">
<channel>
<title>My Personal Blog RSS Feed</title>
<description>
An example Gatsby blog with an automatically generated RSS feed.
</description>
<link>https://my-personal-blog.com</link>
<generator>GatsbyJS</generator>
<lastBuildDate>Wed, 27 Jan 2021 08:07:58 GMT</lastBuildDate>
<item>
<title>My First Post</title>
<description>The first thing I've ever written.</description>
<link>https://my-personal-blog.com/my-first-post/</link>
<guid isPermaLink="false">https://my-personal-blog.com/my-first-post/</guid>
<pubDate>Fri, 01 Jan 2021 00:00:00 GMT</pubDate>
</item>
<item>
<title>Another Great Post</title>
<description>The second thing I've ever written.</description>
<link>https://my-personal-blog.com/another-great-post/</link>
<guid isPermaLink="false">https://my-personal-blog.com/another-great-post/</guid>
<pubDate>Sat, 02 Jan 2021 00:00:00 GMT</pubDate>
</item>
<item>
<title>Yet Another Post</title>
<description>The third thing I've ever written. I'm on a roll!</description>
<link>https://my-personal-blog.com/yet-another-post/</link>
<guid isPermaLink="false">https://my-personal-blog.com/yet-another-post/</guid>
<pubDate>Sun, 03 Jan 2021 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
If it worked, congratulations, your site now has an automatically generated RSS feed! If it didn't, try checking out the Troubleshooting Errors section. (If your problem isn't listed there, reach out to me on Twitter and I'll try to help debug!)
Step 4: (Optional) Add a link to your RSS feed to your site
Now that you've done all this work to generate an RSS feed for your site, it's time to make it discoverable by your readers! (This step is technically optional, although it's probably a good idea if you want people to actually find your RSS feed.)
Use Gatsby's <Link>
component to add a link to your RSS feed somewhere on your home page. (Not sure where to put it? The header or footer is a good start.)
// import { Link } from 'gatsby'
<Link to="/rss.xml">RSS feed</Link>
If your prod build is still running from Step 3, you'll need to kill the server (with ctrl + c
or by closing the terminal window) and rerun the build/serve command to see your changes. (Production builds don't have hot reloading, so you need to restart the server for your changes to be picked up.)
And you're done! The next time you deploy your site, you should be able to visit <your-domain>/rss.xml
(or whatever you configured output
to be) and see your own RSS feed.
Troubleshooting Errors
To help troubleshoot, here are some of the errors I ran into as I was implementing this on my own site, as well as the solution for how I fixed the problem.
Cannot query field "siteUrl" on type "SiteSiteMetadata".
The Error Message:
ERROR #11321 PLUGIN
"gatsby-plugin-feed" threw an error while running the onPostBuild
lifecycle:
Cannot query field "siteUrl" on type "SiteSiteMetadata".
GraphQL request:7:11
6 | description
7 | siteUrl
| ^
8 | site_url: siteUrl, Cannot query field "siteUrl" on type
"SiteSiteMetadata".
GraphQL request:8:11
7 | siteUrl
8 | site_url: siteUrl
| ^
9 | }
The Underlying Problem: Your site doesn't have site metadata, which the default query in gatsby-plugin-feed
expects there to be.
The Solution: Add site metadata to your gatsby-config.js
file. See Prerequisite: Confirm that you have siteMetadata
.
Cannot query field "fields" on type "MarkdownRemark".
The Error Message:
ERROR #11321 PLUGIN
"gatsby-plugin-feed" threw an error while running the onPostBuild
lifecycle:
Cannot query field "fields" on type "MarkdownRemark".
GraphQL request:16:15
15 | }
16 | fields {
| ^
17 | slug
The Underlying Problem: Your blog posts don't have a slug
field. The default GraphQL query used by gatsby-plugin-feed
expects your MarkdownRemark nodes to have a fields.slug
property. (You can use the GraphiQL explorer to manually inspect the available fields on the MarkdownRemark query and confirm that fields.slug
is not available.)
The Solution: In your configuration for gatsby-plugin-feed
(in the gatsby-config.js
file), make sure the feed.query
option includes a slug
field in the query. See the section on Configuring options.query
and feed.query
in Step 2.
Takeaways
- Adding an RSS feed to your site lets readers get automatic updates when you post new content.
- To add an RSS feed to a Gatsby site, use the
gatsby-plugin-feed
plugin. It only generates RSS feeds on production-style builds.
Wrap It Up
Now that you've added an RSS feed to this sample blog site, try adding one to your own Gatsby site. If you run into problems, you can reach out to me on Twitter and I'll do my best to help troubleshoot.
Want to be notified when I write new content? You can subscribe to the RSS feed for my own blog, or you can follow me on Twitter.
Additional Resources
- Gatsby How-To Guide: Adding an RSS Feed
gatsby-plugin-feed
README- How do RSS Feeds Work
- What is RSS: Intro to RSS feeds and RSS aggregators
- RSS Specification