Building a Podcast Site with Eleventy


When me and John started Ruminate, we didn't know much about hosting podcasts so we decided to go with Simplecast to host and manage the podcast. Seven years later, Simplecast has changed quite a bit to the point that it's hindering rather than helping me post the show. It's not a bad service, but it's overkill for posting one episode every two weeks.

I asked last week if anyone had self-hosted a podcast and a few people I trust said it should be easy enough to do so I got to work. As with most of my projects, I used Eleventy. Eleventy is a very powerful static site generator that this site is built with. This post was very helpful in pointing me in the right direction.

Importing existing posts

The first step was to import the existing 156 episodes into the new site. I had a look at the RSS feed to see what metadata each episode would need. Here is an example from episode 156:

layout: episode
guid: ff7d5a18-c87c-4420-a6dd-965be716aa12
title: "156 - For Listeners Only"
published: "Wed, 7 Dec 2022 20:55:06 +0000"
permalink: 156/index.html
file: ""
length: 10993430
duration: 00:22:49
summary: "Baguettes and Obsidian."
episodeNumber: 156

I created a new script called feedtomarkdown.js, used node-fetch and xml2json to parse the feed, and then looped through each episode to get the data. For the shownotes, I needed to covert that back to markdown with turndown. I also learnt about padStart/padEnd to pad the episode numbers from 21 to 021:

'21'.padStart(3, '0') // 021

Finally I output all the file names into to download all the episodes with wget with consistent naming:

wget -O 001.mp3
wget -O 002.mp3
# and so on

Creating new episodes

I'm hosting the episode files on S3 and I didn't want to have to manually get the filesize, duration, and generate a UUID for each episode so I wrote new.js. This script takes an episode number, finds the mp3 file, reads the duration, title, and summary from the mp3 and outputs a new episode (with a UUID as well). This uses mp3-duration and node-id3 to extract that data. I can then fill in the shownotes and push the new episode.

RSS feed

I was able to replicate the RSS feed from Simplecast with this new setup but for some reason Safari doesn't auto-recognise it as a feed that can be opened in Podcasts/NetNewsWire. If anyone knows what attribute triggers this, I'd love to know.

All of the code for this is on GitHub and you can see see the new website here.