While doing code updates last month I noticed Gatsby RSS generation looked a bit of a mess with graphql queries directly in gatsby-config
(gatsby-plugin-feed
).
The generated RSS feed also did not validate.
I decided to implement my own generation script similar to the script I made for astro
/ nextjs
but using graphql as a source.
I also decided to use atom
for feeds as there are a few advantages over rss
.
Why Not Use a Plugin? #
The problem with blindly using plugins is you have no idea how something is implemented.
Also this site has a different graphql layout for data but all of the plugins I found (apart from gatsby-plugin-feed
) had the graphql query hard coded.
Script Idea #
Here is a basic checklist of requirements for the script.
Gatsby provides excerpt
with graphql so returning an excerpt should be no problem, also most fields are directly available from graphql.
Implementation #
Looking in Gatsby docs it seems the best way to implement a script is to use onPostBuild
node API.
Gatsby Node APIs - onPostBuild
I decided to use jpmonette/feed
as it worked well with my atom feed generation script.
Github - jpmonette/feed: A RSS, Atom and JSON Feed generator for Node.js
As most of the work is done by graphql & gatsby there are very few imports required & the only extra dependency is feed
.
Gatsby GraphQL #
I already had a query setup for the old plugin which returned blog posts using filter
.
allMarkdownRemark(
limit: 20
sort: { frontmatter: { date: DESC } }
filter: { frontmatter: { template: { ne: "page" }, draft: { ne: true } } }
)
This returns tha last 20
entries that do not have page
template & are not marked as a draft
& sorts the output in descending order based on date
.
excerpt(format: PLAIN, pruneLength: 450, truncate: false)
I also used excerpt
to return a snippet for the summary
field in the atom output.
Gatsby - GraphQL Query Options
Feed Generation #
Flow of feed generation.
Code Snippets #
Map over array of blog posts
& Add each post using addItemToFeed
.
Add author using addContributor
.
blogPosts.map((posts) => posts.node).forEach(addItemToFeed(feed, siteMetadata))
feed.addContributor({
name: options.author,
link: siteMetadata.site_url,
})
Write output files async.
await fs.writeFile(`./public/${options.output.atom}`, feed.atom1())
await fs.writeFile(`./public/${options.output.rss2}`, feed.rss2())
await fs.writeFile(`./public/${options.output.json}`, feed.json1())
Source Code #
You can find the full pull request for these changes on github.
Valid Syndication Feed Generation pull request on github
The source for the site is available on github.
Webmentions
No Comments Yet