I decided to create an external script to generate an atom feed from markdown posts as astro doesn't currently support this.
Also @astrojs/rss
has multiple problems
📝 Default RSS Generation In Astro
Script Idea #
Before starting this is a checklist of requirements for the script.
Implementing Excerpt #
I wanted to add an excerpt of the content into the summary field of the atom entries. (most tech blogs I subscribe to do this)
Implementing excerpt can be done in different ways, a lot of implementations just use x
characters.
I decided to do it using words (items seperated by spaces)
To do this I used split(' ')
to split words then take a slice
between 0 to 80 & then join
everything back up.
markdown
.render(content)
.split(' ')
.slice(0, 80)
.join(' ')
Then I passed excerpt into description
field (corresponds to summary
in atom in feed
library)
Fixing Relative Paths #
Using markdown-it
will output relative links & images.
RSS feeds shouldn't have items with relative paths.
To fix this use replace()
on href
& src
objects starting with /
.
markdown
.render(content)
.replace('src="/', `src="${siteConfig.url}/`)
.replace('href="/', `href="${siteConfig.url}/`)
.split(' ')
.slice(0, 80)
.join(' ')
Adding Sanitize #
Wrap markdown-it
with sanitize-html
const excerpt = sanitizeHtml(
markdown
.render(content)
.split(' ')
.slice(0, 50)
.join(' ')
)
Connecting Site Config #
I decided to link the script with config.ts
to make things easier.
There are also type definitions in feed
to use (FeedOptions
)
import { siteConfig } from '~/config'
const options: FeedOptions = {
title: siteConfig.title,
description: siteConfig.description,
id: siteConfig.url + '/',
link: siteConfig.url + '/',
language: 'en',
copyright: `copyright ${year} equk.co.uk all rights reserved`,
author: {
name: siteConfig.author.name,
link: siteConfig.url,
},
favicon: siteConfig.url + '/favicon.svg',
feedLinks: {
atom: siteConfig.url + '/atom.xml',
},
}
Main Function #
Flow of main function (taken from code comments).
Adding CLI Feedback #
Astro gives feedback on build including time taken so it would be nice to add something similar when running builds.
I also want the script to quit & give feedback if an error occurs.
18:36:06 [build] Complete!
./dist/atom.xml created (+63ms)
Adding Atom Generation To Astro Build #
Add the feed generation script to the end of build
in package.json
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build && tsx ./generate-feed.ts",
Comparing Output #
To show the difference in output here is an example.
@astrojs/rss
- /rss.xml (+57ms)
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>equk's blog</title><description>blog of a developer & sysadmin</description><link>https://example.com/</link><item><title>Atom Feed Generation Script</title><link>https://example.com/2023/02/22/atom-feed-generation-script/</link><guid>https://example.com/2023/02/22/atom-feed-generation-script/</guid><description><p> </p>
<p>I decided to create an external script to generate an atom feed from markdown posts as astro doesn't currently support this.</p>
generate-feed.ts
- /atom.xml (+61ms)
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://example.com/</id>
<title>equk's blog</title>
<updated>2023-02-22T11:59:34.243Z</updated>
<generator>https://github.com/jpmonette/feed</generator>
<author>
<name>equilibriumuk</name>
<uri>https://equk.co.uk</uri>
</author>
<link rel="alternate" href="https://example.com/"/>
<link rel="self" href="https://example.com/atom.xml"/>
<subtitle>blog of a developer & sysadmin</subtitle>
<icon>https://example.com/favicon.svg</icon>
<rights>copyright 2023 equk.co.uk all rights reserved</rights>
<entry>
<title type="html"><![CDATA[Atom Feed Generation Script]]></title>
<id>https://example.com/2023/02/22/atom-feed-generation-script/</id>
<link href="https://example.com/2023/02/22/atom-feed-generation-script/"/>
<updated>2023-02-22T10:58:02.079Z</updated>
<summary type="html"><![CDATA[<p> </p>
<p>I decided to create an external script to generate an atom feed from markdown posts as astro doesn't currently support this.</p>
Advantages Over Astrojs/RSS #
As feed
is used, it's also possible to output to json
or rss
with little modification.
Source #
The source for my astro blog is available on github.
Webmentions
No Comments Yet