How To Add Custom Fields to Your Gatsby RSS Feed
Harrison Reid
Posted on July 6, 2020
I've recently launched a product I've been working on for while: Ippy.io - a better resume builder. It's live on Product Hunt now, so check it out here if you're interested š
What youāll learn:
- How to declare custom namespaces on your Gatsby RSS feed
- How to use the namespaces to add custom elements
What youāll build:
- An RSS feed with custom data!
Iāve recently been working on adding up an RSS feed for Days of Dev using gatsby-plugin-feed.
While setting this up, I found myself facing a small roadblock; I wanted to add additional custom data to the RSS feed, and couldnāt figure out how to get it working. Specifically, I wanted to add the full text of tweets that Iād auto generate from various frontmatter fields.
This would allow me to easily post to my social accounts through Zapier without having to mess around with any complex logic to compose the tweets in Zapier itself (and importantly, let me avoid having to pay for a premium account!).
It wasnāt immediately clear to me from the Gatsby docs how to get this working, so I thought Iād post this up here in case anyone faces the same problem in the futture!
Itās worth noting it is actually documented, but itās included under a header explaining how to add iTunes RSS blocks, which I didnāt pick up on initially.
The Key: Namespaces
If you, like me, know next to nothing about RSS, you mightāve assumed that you can just throw any XML into an RSS feed. Well, actually, you pretty much can! But there is a slight catchā¦
To add custom elements (with custom data), you need to namespace them.
Fortunately, this is reasonably straightforward (particularly because weāre using gatsby-plugin-feed). Basically, it means that in the output XML, you need to declare the namespace, then prefix all of your custom xml tags with the declared namespace.
For example, in the RSS feed for Days of Dev (available at daysof.dev/rss.xml), youāll see the namespace declaration in the opening <rss>
tag - xmlns:daysofdev="https://www.daysof.dev"
.
Then, when Iāve added custom data, the tag name is always prefixed with the namespace followed by a colon. For example, the tag containing the tweet for a given post is included as: <daysofdev:tweet>Some text...</daysofdev:tweet>
Setting up gatsby-plugin-feed
Using gatsby-plugin-feed to set up namespaces, and include custom data, is relatively straightforward.
To start with, follow the instructions in the gatsby docs to customise the RSS feed plugin.
This should leave you with a gatsby-config.js with a plugin config for gatsby-plugin-feed that looks something like the following. Note that Iāve excluded a number of the option fields here for brevity, so directly copy-pasting the whole snippet will almost certainly cause you problems.
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-feed`,
options: {
feeds: [
{
serialize: ({
query: { allMarkdownRemark },
}) => {
return allMarkdownRemark.edges.map((edge) => {
return Object.assign(
{},
edge.node.frontmatter,
{
...
custom_elements: [
{ "content:encoded": edge.node.html },
],
}
);
});
},
...
},
],
},
},
],
};
To include a custom element, we need to make two changes:
Firstly, we need to tell gatsby-plugin-feed about the namespace we wish to declare. This is achieved by adding the setup
option, which extends the options with a custom_namespaces
field. In this example, weāve added yournamespace. I donāt think the URL value of the is particularly important, as long as itās unique to your namespace.
Secondly, we include the custom element under the custom_elements
field in the output of the serialize
function. You can see this added in the example as:
{ "yournamespace:yourcustomfield": edge.node.fields.someField }
Note that the custom element name must use the namespace, followed by a colon.
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-feed`,
options: {
setup: (options) => ({ ...options, custom_namespaces: { yournamespace: "https://www.yournamespace.com", }, }), feeds: [
{
serialize: ({
query: { allMarkdownRemark },
}) => {
return allMarkdownRemark.edges.map((edge) => {
return Object.assign(
{},
edge.node.frontmatter,
{
...
custom_elements: [
{ "content:encoded": edge.node.html },
{ "yournamespace:yourcustomfield": edge.node.fields.someField } ],
}
);
});
},
},
],
...
},
},
],
};
This should be all you need to add arbitrary custom data to your RSS feed generated by gatsby-plugin-feed. When you next deploy your app, you should have the custom data available to make use of wherever your RSS feed is being consumed.
Posted on July 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.