Chronoblog (Gatsby) theme with RSS feed
Tags: gatsby
Published: 2023-01-26 20:38:15

---
title: Chronoblog (Gatsby) theme with RSS feed
published: true
tags: ['gatsby']
canonical_url: https://sevic.dev/notes/chronoblog-gatsby-rss/
---

Chronoblog is one of the Gatsby blogging themes. RSS feed can be used to get the latest posts for Github actions, `dev.to`, etc. The following steps can easily add it. Use a similar approach for other Gatsby themes.

### Initial setup

Run the following commands to clone the repository and install the required packages.

```bash
npx gatsby new chronoblog-site https://github.com/Chronoblog/gatsby-starter-chronoblog
cd chronoblog-site
npm i gatsby-plugin-feed@2 gatsby-transformer-remark@3 gatsby-source-filesystem
```

### GraphQL setup

Populate GraphQL fields to avoid null errors. Add `canonical_url: http://example.com` to content &#8594; links &#8594; frontmatter-placeholder &#8594; index.md file.

### Gatsby config

Add plugin configurations in `gatsby-config.js`. Draft content, links, and placeholder post are skipped.

```js
module.exports = {
  // ...
  plugins: [
    // ...
    {
      resolve: `gatsby-plugin-feed`,
      options: {
        query: `
          {
            site {
              siteMetadata {
                title
                description
                siteUrl
                site_url: siteUrl
              }
            }
          }
        `,
        feeds: [
          {
            serialize: ({ query: { site, allMarkdownRemark } }) => {
              return allMarkdownRemark.edges.map(edge => {
                return Object.assign({}, edge.node.frontmatter, {
                  description: edge.node.excerpt,
                  date: edge.node.frontmatter.date,
                  url: edge.node.frontmatter.canonical_url || edge.node.frontmatter.url,
                  guid: edge.node.frontmatter.canonical_url || edge.node.frontmatter.url,
                  custom_elements: [{ "content:encoded": edge.node.html }],
                })
              })
            },
            query: `
              {
                allMarkdownRemark(
                  filter: { 
                    frontmatter: {
                      draft: { ne: true },
                      link: { eq: null },
                      title: { ne: "Ghost Post" }
                    },
                  },
                  sort: { order: DESC, fields: [frontmatter___date] },
                ) {
                  edges {
                    node {
                      excerpt
                      html
                      fields { slug }
                      frontmatter {
                        title
                        canonical_url
                        date
                      }
                    }
                  }
                }
              }
            `,
            output: "/rss.xml",
            title: "RSS Feed",
          },
        ],
      },
    },
    {
      resolve: `gatsby-transformer-remark`
    },
  ],
  // ...
};
```

### Gatsby node setup

Implement `onCreateNode` function in `gatsby-node.js` file

```js
const { createFilePath } = require(`gatsby-source-filesystem`);

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}
```

### Npm scripts setup

Add `serve` script in `package.json`

```json
{
  // ...
  "scripts": {
    // ...
    "serve": "gatsby serve"
  }
}
```

### Demo

Run `npm run build && npm run serve`. RSS feed should be populated on [http://localhost:9000/rss.xml](http://localhost:9000/rss.xml) page.