Create an 11ty collection from any RSS feed

A post from the future!

You may have noticed this post is dated in the future. I do this to keep myself on a regular writing schedule and to mask the flurries of activity I'm prone to. You can see all of my upcoming posts if you want a sneak peak

Please feel free to read and share as you normally would.

This method parses the RSS feed as actual RSS which makes the feed slightly easier to process. If you are looking to extract more meta data or unconventional information stored in the feed, it might be worth reading the next post, Making an 11ty collection from a remote XML file.

This post also builds on previous methodologies covered in a previous post - Creating an 11ty collection from a JSON API

A friend of mine is a YouTuber and was enquiring about having a landing page which auto updated with his latest videos. My mind immediately jumped to 11ty and have a static site which rebuilds on a new feed item.

Disclaimer: I'm sure there are other solutions, but 11ty is where I am at the moment.

YouTube allows you to get an RSS feed of a YouTube channel by doing the following (replacing [channel_id] with the ID of the channel)

https://www.youtube.com/feeds/videos.xml?channel_id=[channel_id]

With the RSS feed, we can make a 11ty data file, parse the feed into JSON and return it. This may sound complex, but fortunately there is an npm package that does the heavy lifting.

Note: If you are unsure about dynamic 11ty data files and turning them into collections, have a skim over my last post to give you some background

Install the package:

npm i --save rss-parser

Inside your JavaScript data file (I called mine videos.js), require the package and initialise the parser

const Parser = require('rss-parser');
const parser = new Parser();

let rss_feed = 'https://www.youtube.com/feeds/videos.xml?channel_id=[channel_id]';

module.exports = async function() {
return await parser.parseURL(rss_feed);
};

In your 11ty files, you can now loop through the videos and access all the properties in the feed:

{% for video in videos %}
<h3>{{ video.title }}</h3>
{% endfor %}

You may notice in the parsed RSS, the YouTube video ID doesn't exist. It is in the RSS but as it doesn't conform to standard RSS standards, the parser doesn't grab it.

For that, you can post-process the data. In the example below I add the code and also create the URL for the thumbnail:

const Parser = require('rss-parser');
const parser = new Parser();

const rss_feed = 'https://www.youtube.com/feeds/videos.xml?channel_id=[channel_id]';

module.exports = async function() {

let feed = await parser.parseURL(rss_feed);

let data = feed.items.map((video) => {
let guid = video.id.split(':');
video.code = guid[2];
video.image = `https://i3.ytimg.com/vi/${video.code}/maxresdefault.jpg`;
return video;
});

return data;
};

With the ID/code in your data you can either create a link off to YouTube

{% for video in videos %}
<a href="https://www.youtube.com/watch?v={{ video.code }}">
<img src="{{ video.image }}" width="120">
<h3>{{ video.title }}</h3>
</a>
{% endfor %}

Alternatively, you can create the embed code:

<iframe width="560" height="315" src="https://www.youtube.com/embed/{{ video.code }}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
This website is currently having a full content audit - apologies if some of the code or content looks a bit funky!

View this post on Gitlab

You might also enjoy…

Mike Street

Written by Mike Street

Mike is a front-end developer from Brighton, UK. He spends his time writing, cycling and coding. You can find Mike on Twitter.