How to generate RSS.xml files from Sanity posts with gatsby-plugin-feed

5 replies
Last updated: Jan 12, 2021
hey all, is it possible to combine
allSanityPost
and
allMdx
for
gatsby-plugin-feed
and spits out both content on
rss.xml
? Have anyone managed to figure that out? Google only return
user Y
gist and I have used them as reference but only managed to create 2 separate feeds for both MDX and Sanity instead of combining them both into one: https://github.com/ajmalafif/afif.dev/pull/46
AI Update

Looking at your PR and the challenge you're facing, yes, it's definitely possible to combine allSanityPost and allMdx into a single RSS feed with gatsby-plugin-feed! The key is to merge the results from both GraphQL queries into one unified array before passing them to the feed serializer.

Here's the approach that should work:

{
  resolve: `gatsby-plugin-feed`,
  options: {
    query: `
      {
        site {
          siteMetadata {
            title
            description
            siteUrl
            site_url: siteUrl
          }
        }
      }
    `,
    feeds: [
      {
        serialize: ({ query: { site, allSanityPost, allMdx } }) => {
          // Combine both sources into a single array
          const sanityPosts = allSanityPost.nodes.map(node => ({
            title: node.title,
            description: node.excerpt,
            date: node.publishedAt,
            url: site.siteMetadata.siteUrl + '/blog/' + node.slug.current,
            guid: site.siteMetadata.siteUrl + '/blog/' + node.slug.current,
            custom_elements: [{ "content:encoded": node._rawBody }],
          }));

          const mdxPosts = allMdx.nodes.map(node => ({
            title: node.frontmatter.title,
            description: node.excerpt,
            date: node.frontmatter.date,
            url: site.siteMetadata.siteUrl + node.fields.slug,
            guid: site.siteMetadata.siteUrl + node.fields.slug,
            custom_elements: [{ "content:encoded": node.html }],
          }));

          // Merge and sort by date (most recent first)
          return [...sanityPosts, ...mdxPosts].sort((a, b) => 
            new Date(b.date) - new Date(a.date)
          );
        },
        query: `
          {
            allSanityPost(sort: {publishedAt: DESC}) {
              nodes {
                title
                slug {
                  current
                }
                publishedAt
                excerpt
                _rawBody
              }
            }
            allMdx(sort: {frontmatter: {date: DESC}}) {
              nodes {
                excerpt
                html
                fields {
                  slug
                }
                frontmatter {
                  title
                  date
                }
              }
            }
          }
        `,
        output: "/rss.xml",
        title: "Your Site's RSS Feed",
      },
    ],
  },
}

The critical parts:

  1. Query both sources in the same feed configuration
  2. Map each source to a common structure with the same fields (title, description, date, url, etc.)
  3. Combine the arrays using the spread operator [...sanityPosts, ...mdxPosts]
  4. Sort by date to ensure chronological order regardless of source

You'll need to adjust the field mappings based on your actual schema (like how you're storing content in Sanity, whether you're using portable text or markdown, etc.), but this pattern should give you a single rss.xml file with content from both sources merged together.

The reason you were getting two separate feeds before was likely because you had two separate feed objects in the feeds array. This approach keeps it as one feed configuration that pulls from multiple GraphQL sources.

Show original thread
5 replies
hi Ajmal, are you trying to combine the results of
allSanityPost
and
allMdx
into a single feed? So there will be 1 item in the feed for each
mdx
and 1 item for each
sanityPost
, correct?
If that's what you're after you should be able to do something like this:

https://gist.github.com/dylanjha/d92e491f867a41f75df13501d835f51b/revisions
Notice that in that most recent commit I refactored what you had so that
serialize()
returns a single array (
records
).
We iterate through
allSanityPost
and add each one to the
records
array. Then iterate through
allMdx
and do the same. After all of that we return the single
records
array
hey
Dylan Jhaveri
thanks so much!
Yes that is exactly what I wanted to make and it works now
i messed up the mdx part so im posting the one im using in the codebase (the gist one wasnt updated) on top of your help if thats okay

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?