DevelopmentGatsbyJS | 6 Min Read

Making an RSS Feed for a Gatsby Mdx Blog

MDX and GatsbyJS is a powerful combination for blogs. But, making an RSS feed takes a bit more set-up, here's how to do it.

Gatsby and RSS feeds.

By default you can use markdown with Gatsby to create blog posts and this is fine for basic posts but Mdx takes the best things about markdown and goes one step further introducing the ability to use full ReactJS components inside your markdown blog posts opening up the possibilities tenfold. (If you're interested in reading more about the changes Mdx gives us, you can read more on their docs here.)

If you were to go ahead with using normal markdown on your Gatsby site you could use the 'gatsby-plugin-feed' to generate an RSS feed for your site but when using Mdx we don't have this option by default so this is what we are going to cover in this blog post, how to take the aforementioned plugin and change it to work with Mdx.

I should mention before beginning that this work has already been completed and released as a plugin 'gatsby-plugin-feed-mdx'. So, if you want to quickly get your site up and running you can use this plugin. But, if you are curious like me how to get this working using the original plugin, stick around because I promise you it is a lot simpler than you think.

Plugin Set-Up

Before we get started on customising the original plugin we first need to get it actually set-up as if we we're going to use it on a normal markdown site. You can do start by installing the plugin on your Gatsby site by using the following command:

1npm install --save gatsby-plugin-feed
jsx

With the plugin installed, hop into your 'gatsby-config.js' and paste the below configuration into your plugins array:

1{
2 resolve: `gatsby-plugin-feed`,
3 options: {
4 query: `
5 {
6 site {
7 siteMetadata {
8 title
9 description
10 siteUrl
11 site_url: siteUrl
12 }
13 }
14 }
15 `,
16 feeds: [
17 {
18 serialize: ({ query: { site, allMarkdownRemark } }) => {
19 return allMarkdownRemark.edges.map(edge => {
20 return Object.assign({}, edge.node.frontmatter, {
21 description: edge.node.excerpt,
22 date: edge.node.frontmatter.date,
23 url: site.siteMetadata.siteUrl + edge.node.fields.slug,
24 guid: site.siteMetadata.siteUrl + edge.node.fields.slug,
25 custom_elements: [{ "content:encoded": edge.node.html }],
26 })
27 })
28 },
29 query: `
30 {
31 allMarkdownRemark(
32 sort: { order: DESC, fields: [frontmatter___date] },
33 ) {
34 edges {
35 node {
36 excerpt
37 html
38 fields { slug }
39 frontmatter {
40 title
41 date
42 }
43 }
44 }
45 }
46 }
47 `,
48 output: "/rss.xml",
49 title: "Your Site's RSS Feed",
50 // optional configuration to insert feed reference in pages:
51 // if `string` is used, it will be used to create RegExp and then test if pathname of
52 // current page satisfied this regular expression;
53 // if not provided or `undefined`, all pages will have feed reference inserted
54 match: "^/blog/",
55 // optional configuration to specify external rss feed, such as feedburner
56 link: "https://feeds.feedburner.com/gatsby/blog",
57 },
58 ],
59 },
60},
jsx

After pasting in this initial set-up you may need to change a few queries to get all the correct data pulled through, mainly this will be the siteMetadata query ran at the top of the plugin configuration, you need to make sure the queried fields line up with the fields you have defined in your siteMetadata further up in your 'gatsby-config.js' file.

If they don't align then you may need to change your siteMetadata configuration or alternatively set-up aliasing for the GraphQL query. This is outside the aim of this blog post but you can learn more about GraphQL aliasing here.

Once you have this set-up, you may also want to change the 'output' and 'title' properties returned (in the plugin configuration) as this is the URL endpoint your RSS feed can be found on and the title of it. I'll leave these up to you if you change them.

If at any point you want an example to look at you can check out my site's 'gatsby-config.js' file on the GitHub Repo for my site here.

Plugin changes

With all of the original plugin set-up completed, let's look at the changes we need to complete and I promise you there isn't a lot.

First of all, we need to change all the references to 'allMarkdownRemark' in the plugin configuration to 'allMdx', below the lines you need to change are highlighted:

1{
2 resolve: `gatsby-plugin-feed`,
3 options: {
4 query: `
5 {
6 site {
7 siteMetadata {
8 title
9 description
10 siteUrl
11 site_url: siteUrl
12 }
13 }
14 }
15 `,
16 feeds: [
17 {
18 serialize: ({ query: { site, allMdx } }) => {
19 return allMdx.edges.map(edge => {
20 return Object.assign({}, edge.node.frontmatter, {
21 description: edge.node.excerpt,
22 date: edge.node.frontmatter.date,
23 url: site.siteMetadata.siteUrl + edge.node.fields.slug,
24 guid: site.siteMetadata.siteUrl + edge.node.fields.slug,
25 custom_elements: [{ "content:encoded": edge.node.html }],
26 })
27 })
28 },
29 query: `
30 {
31 allMdx(
32 sort: { order: DESC, fields: [frontmatter___date] },
33 ) {
34 edges {
35 node {
36 excerpt
37 html
38 fields { slug }
39 frontmatter {
40 title
41 date
42 }
43 }
44 }
45 }
46 }
47 `,
48 output: "/rss.xml",
49 title: "Your Site's RSS Feed",
50 // optional configuration to insert feed reference in pages:
51 // if `string` is used, it will be used to create RegExp and then test if pathname of
52 // current page satisfied this regular expression;
53 // if not provided or `undefined`, all pages will have feed reference inserted
54 match: "^/blog/",
55 // optional configuration to specify external rss feed, such as feedburner
56 link: "https://feeds.feedburner.com/gatsby/blog",
57 },
58 ],
59 },
60},
jsx{19,

With this changed, you can run the RSS feed but it doesn't quite work as expected and that's because there is one more file we need to change. The actual 'gatsby-plugin-feed' gatsby-node.js file which is contained inside of the node_modules folder for your project. I found the file at:

1/
2 node_modules
3 gatsby-plugin-feed
4 gatsby-node.js

Once, you have located the file, we just need to repeat what we did above and change all references of 'allMarkdownRemark' to 'allMdx' inside of the serialize function, once complete it should look like this:

1var serialize = function serialize(_ref) {
2 var _ref$query = _ref.query,
3 site = _ref$query.site,
4 allMdx = _ref$query.allMdx;
5 return allMdx.edges.map(function (edge) {
6 return (0, _extends2.default)((0, _extends2.default)({}, edge.node.frontmatter), {}, {
7 description: edge.node.excerpt,
8 url: site.siteMetadata.siteUrl + edge.node.fields.slug,
9 guid: site.siteMetadata.siteUrl + edge.node.fields.slug,
10 custom_elements: [{
11 "content:encoded": edge.node.html
12 }]
13 });
14 });
15};
jsx{4-5}

Once, all of these changes have been made, we should now be able to stop the Gatsby server and run the following command to build and serve the changed files including the RSS Feed:

1gatsby build && gatsby serve
jsx

This is important because 'gatsby-plugin-feed' will only generate an RSS feed when ran in production mode so if no RSS feed is showing up, please first check that you are running in production mode. If you are still receiving issues, go back over the above and see if you have missed anything and if not you can reach out to me on Twitter @MrConerMurphy and I would be happy to help.

Conclusion

To finish this post I want to address why you might want to do this as compared to using the 'gatsby-plugin-feed-mdx' plugin.

If I'm being honest I made the choice to customise the original plugin for my site because I was curious as to how the original plugin could be changed to support Mdx like the Mdx plugin but other than this there isn't many reasons to not use the Mdx plugin. I mean there is a chance if the original plugin is updated the Mdx plugin may not receive the updates or be delayed due to less support or some other reason but overall you could use the Mdx plugin and be fine.

I hope you found this post helpful and if you did then I would greatly appreciate it if you could share the post with someone else who may also find it helpful.

If you have any questions please contact me using the links below and I would be happy to answer them.



Content

Latest Blog Posts

Below is my latest blog post and a link to all of my posts.

View All Posts

Content

Latest Video

Here is my YouTube Channel and latest video for your enjoyment.

View All Videos
AWS Bedrock Text and Image Generation Tutorial (AWS SDK)

AWS Bedrock Text and Image Generation Tutorial (AWS SDK)

Contact

Join My Newsletter

Subscribe to my weekly newsletter by filling in the form.

Get my latest content every week and 0 spam!