Enea Xharja Logo

Add an RSS Feed to your Gatsby MDX blog

An RSS Feed is a standard XML file with the purpose of listing the content of a website in a subscribable format. It allows readers to consume your content in news aggregators, like a feed reader app. You can think of it like a newsfeed where the content is displayed in a chronological order, without any algorithm choosing the "right" post that will make you click.

Install

To generate an RSS Feed for your Gatsby MDX blog, you need the gatsby-plugin-feed-mdx package. To install this package, run the following command:

bash
1npm install --save gatsby-plugin-feed-mdx

Config

Now, it's time to config the gatsby-plugin-feed-mdx plugin in your gatsby-config.js file:

js
1{
2 // Enables RSS Feed
3 resolve: `gatsby-plugin-feed-mdx`,
4 options: {
5 query: `
6 {
7 site {
8 siteMetadata {
9 title
10 description
11 siteUrl
12 site_url: siteUrl
13 }
14 }
15 }
16 `,
17 feeds: [
18 {
19 serialize: ({ query: { site, allMdx } }) =>
20 allMdx.edges.map(edge => ({
21 ...edge.node.frontmatter,
22 description: edge.node.excerpt,
23 date: edge.node.frontmatter.date,
24 url: `${site.siteMetadata.siteUrl}/blog${edge.node.frontmatter.slug}`,
25 guid: `${site.siteMetadata.siteUrl}/blog${edge.node.frontmatter.slug}`,
26 custom_elements: [{ 'content:encoded': edge.node.html }],
27 })),
28 query: `
29 {
30 allMdx(
31 sort: { order: DESC, fields: [frontmatter___date] },
32 filter: { frontmatter: { published: { eq: true } } }
33 ) {
34 edges {
35 node {
36 excerpt
37 html
38 frontmatter {
39 title
40 slug
41 date(formatString: "MMMM DD, YYYY")
42 }
43 }
44 }
45 }
46 }
47 `,
48 output: '/rss-feed.xml',
49 title: "Enea'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: '^/posts/',
55 },
56 ],
57 },
58}

We can have a closer look at all this block of code by examining each option individually. The initial query attribute allows us to query for site metadata:

js
1query: `
2 {
3 site {
4 siteMetadata {
5 title
6 description
7 siteUrl
8 site_url: siteUrl
9 }
10 }
11 }
12`,

The query attribute is followed by a feeds array, that we can use to create multiple feeds. This can be usefull if you want to generate different feeds for different content types like: blog, courses, podcast or talks. Every content type will be represented by a feed object:

js
1feeds: [
2 {
3 // blog feed
4 },
5 {
6 // courses feed
7 },
8 {
9 // podcast feed
10 },
11 {
12 // talks feed
13 },
14];

Since we are working with an MDX Blog, we need to transform our MDX pages into HTML objects that can be read by RSS Feed readers. For this purpose, we need to use a serializer:

js
1serialize: ({ query: { site, allMdx } }) =>
2 allMdx.edges.map(edge => ({
3 ...edge.node.frontmatter,
4 description: edge.node.excerpt,
5 date: edge.node.frontmatter.date,
6 url: `${site.siteMetadata.siteUrl}/blog${edge.node.frontmatter.slug}`,
7 guid: `${site.siteMetadata.siteUrl}/blog${edge.node.frontmatter.slug}`,
8 custom_elements: [{ 'content:encoded': edge.node.html }],
9 })),

Our feed object will contain also a GraphQL query that will retrieve all our blog posts and sort them in descending order, before filtering out those which are just drafts:

js
1query: `
2 {
3 allMdx(
4 sort: { order: DESC, fields: [frontmatter___date] },
5 filter: { frontmatter: { published: { eq: true } } }
6 ) {
7 edges {
8 node {
9 excerpt
10 html
11 frontmatter {
12 title
13 slug
14 date(formatString: "MMMM DD, YYYY")
15 }
16 }
17 }
18 }
19 }
20`,

Finally, we need to specify our RSS Feed URL together with a title using the output and title attributes.

Output

To see the final output, you can run the following command in your terminal:

bash
1gatsby build && gatsby serve

and visit http://localhost:9000/rss-feed.xml.

For reference, here is my entire gatsby-config.js file.