29.5 RSS Feed Customization
Right, so you want an RSS feed. Not just any feed, but your feed. One that doesn’t look like it was generated by a bored robot in 2003. Good. RSS is a cranky old standard, but it’s far from dead. It’s the un-opinionated, user-centric backbone of the independent web that refuses to die, and customizing it is a small act of rebellion. Let’s make yours brilliant.
The core truth you must accept is that an RSS feed is just XML. Not scary, magical XML, but a specific, documented XML format. Your job is to generate that XML correctly. Most frameworks have some built-in RSS generator, and they’re usually… fine. But “fine” is for cowards. We’re going to bend it to our will.
The Absolute Basics: What Actually Goes In There
Before you start customizing, you need to know what you’re working with. A basic feed has two main parts: the channel metadata (the info about your site) and the items (your posts). The minimum viable feed requires this:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Your Brilliant Blog</title>
<link>https://yourblog.com</link>
<description>Where I rant about tech and probably cats.</description>
<!-- Now for the good stuff -->
<item>
<title>My First Post</title>
<link>https://yourblog.com/first-post</link>
<description>This is the summary or full content of your post.</description>
<pubDate>Mon, 15 Aug 2022 12:00:00 GMT</pubDate>
<guid isPermalink="true">https://yourblog.com/first-post</guid>
</item>
</channel>
</rss>
See? Not so bad. But let’s call out the first bit of absurdity: pubDate. That date format is ridiculous. It’s RFC 822, revised by RFC 1123. No, I’m not joking. You must get this format exactly right, or RSS readers will silently ignore your date and your posts will be ordered like a madlib. Most languages have libraries for this (date_format(DATE_RSS) in PHP, strftime in Ruby, etc.). Use them. Do not try to concatenate this string by hand. I’ve done it. You will get it wrong at 2 AM.
Going Beyond the Basic <description>
Here’s the first big customization choice: what do you put in the <description> tag? By default, most generators just shove in a text excerpt. This is a tragedy. For maximum compatibility, you should put the full content of your post in there. Why? Because many readers (like the beloved old Google Reader) primarily displayed this field. An excerpt just forces a click-through.
But we can do better. Wrap your HTML content in a CDATA section so the XML parser doesn’t get heartburn trying to escape all your angled brackets.
<item>
<title>Why RSS is Still Awesome</title>
<link>https://yourblog.com/why-rss</link>
<description><![CDATA[
<p>Look, another social network just got acquired and ruined. Again.</p>
<p>This is why you need an RSS feed. <em>You</em> control the content.</p>
<img src="https://yourblog.com/img/in-control.gif" alt="You're in control!">
]]></description>
<pubDate>Mon, 15 Aug 2022 12:00:00 GMT</pubDate>
<guid isPermalink="true">https://yourblog.com/why-rss</guid>
</item>
This ensures your formatting, links, and images show up right inside the RSS reader. It’s the difference between a rich experience and a sad text snippet.
The guid Field: A Deceptively Important Mess
The <guid> is the “globally unique identifier” for your post. It’s what readers use to know if they’ve seen this item before. The spec says it can be any unique string, but here’s the trench wisdom: make it the permalink. Always. And crucially, add isPermalink="true" to it.
Why? Because if you change your domain name from http to https, or from yourblog.com to yourblog.blog, some readers will see the new URL (in <link>) and the old guid and think it’s a new post. They’ll show your entire backlog to your poor subscribers. It’s a nightmare. Making the guid the permalink and marking it as such future-proofs you against this chaos. If you can’t use the permalink (maybe you have some legacy system), then the guid must be immutable and permanent. No excuses.
Adding Modern Features: Cover Images and Content
RSS 2.0 is ancient, so we use XML namespaces to extend it. The most common one is the Content Module (xmlns:content="http://purl.org/rss/1.0/modules/content/"). This lets you provide a clean separation between a summary (for the old-school <description>) and the full encoded content.
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>Your Brilliant Blog</title>
<link>https://yourblog.com</link>
<description>Where I rant about tech and probably cats.</description>
<!— It's a good idea to add a channel-level image too —>
<image>
<url>https://yourblog.com/icon.jpg</url>
<title>Your Brilliant Blog</title>
<link>https://yourblog.com</link>
</image>
<item>
<title>Why RSS is Still Awesome</title>
<link>https://yourblog.com/why-rss</link>
<!— For backwards compatibility —>
<description>A rant about the modern web.</description>
<!— For modern readers —>
<content:encoded><![CDATA[
<p>Look, another social network just got acquired and ruined. Again.</p>
<p>This is why you need an RSS feed. <em>You</em> control the content.</p>
]]></content:encoded>
<pubDate>Mon, 15 Aug 2022 12:00:00 GMT</pubDate>
<guid isPermalink="true">https://yourblog.com/why-rss</guid>
</item>
</channel>
</rss>
Validating Your Masterpiece
Do not, I repeat, DO NOT just assume your generated XML is valid. It almost certainly isn’t on the first try. You will have an unescaped ampersand or a weird character hiding in there. Use a validator. The W3C Feed Validation Service is the gold standard. Paste your feed’s URL in there and fix every single error it finds. It’s tedious, but a broken feed is worse than no feed at all—it betrays the trust of everyone who subscribes to it.
Your feed is your direct line to your most engaged audience. Taking the time to customize it properly isn’t just pedantry; it’s a sign of respect for them and for your own work. Now go make something that doesn’t suck.