How to publish an RSS 2.0 feed
We list RSS 2.0 feeds only, and that’s our constraint, not a judgement about yours. This page is the shortest path from “we found a feed, just not an RSS 2.0 one” to being listed — on most platforms it’s a five-minute change, and you keep your existing feed.
The autodiscovery tag
This is how we (and every reader) find your feed. One line in your
<head>:
<link rel="alternate" type="application/rss+xml"
title="Your site name" href="/feed.xml">
The non-obvious part: it has to be on
the page your feed’s <channel><link> points
at. If your feed says it belongs to https://example.com/, then
https://example.com/ is the page that needs this tag — not just
your blog index, and not only your post pages. That’s the page we list, so
that’s the page we read.
type="application/rss+xml" exactly. text/xml and
application/atom+xml are the two spellings that get sites rejected
here.
If your page advertises several feeds, we take the first RSS 2.0 one. Put the one you want listed first.
The <channel><link>
Inside your feed, <channel><link> names the site the feed
belongs to. A wrong value here is the single most confusing rejection we
produce, because everything looks fine from where you’re standing.
<channel>
<title>Your site name</title>
<link>https://example.com/</link>
<description>What you write about</description>
It should be your site — usually your homepage or your blog index — not the feed’s own URL, and not the URL of your most recent post. We publish that value as your listing, and we check the two point at each other: your page declares your feed, and your feed names your page. That mutual check is what stops anyone listing your feed under their own URL.
Jekyll / GitHub Pages
jekyll-feed gives you Atom at /feed.xml. Keep it, and add
RSS 2.0 alongside. Create rss.xml in your site root:
---
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ site.title | xml_escape }}</title>
<link>{{ site.url }}{{ site.baseurl }}/</link>
<description>{{ site.description | xml_escape }}</description>
<language>en</language>
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
<atom:link href="{{ site.url }}{{ site.baseurl }}/rss.xml"
rel="self" type="application/rss+xml" />
{% for post in site.posts limit:20 %}
<item>
<title>{{ post.title | xml_escape }}</title>
<link>{{ site.url }}{{ post.url }}</link>
<guid isPermaLink="true">{{ site.url }}{{ post.url }}</guid>
<pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
<description>{{ post.content | xml_escape }}</description>
</item>
{% endfor %}
</channel>
</rss>
Then add the tag to your layout’s <head>:
<link rel="alternate" type="application/rss+xml"
title="{{ site.title }}" href="{{ '/rss.xml' | absolute_url }}">
site.url must be set in _config.yml — without it
every link in the feed comes out relative, and <channel><link>
comes out empty.
Eleventy
@11ty/eleventy-plugin-rss ships an RSS 2.0 sample alongside the Atom
one. Copy feed.njk from the plugin’s sample templates, choose the
RSS 2.0 variant, and point permalink at /rss.xml. Set
metadata.url in your data file — the plugin builds
<channel><link> from it. Then add the
autodiscovery tag to your base layout.
Zola
In config.toml:
generate_feeds = true
feed_filenames = ["rss.xml"]
base_url = "https://example.com"
Zola ships a built-in rss.xml template and switches to it based on the
filename, so this is usually the whole change. base_url is what becomes
<channel><link>. Zola inserts the autodiscovery tag itself
if your template calls {% block extra_head %}; check the rendered
<head>.
Astro
@astrojs/rss already emits RSS 2.0, so this is usually just the missing
<head> link. Confirm site is set in
astro.config.mjs — the rss() helper builds
<channel><link> from it and silently omits it otherwise:
export default defineConfig({ site: 'https://example.com' });
Then in your layout:
<link rel="alternate" type="application/rss+xml"
title="Your site" href={new URL('rss.xml', Astro.site)} />
Hand-rolled: a complete template
A minimal, valid RSS 2.0 document. Fill in the five values, keep the structure, and it will pass. You can also download it.
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Your site name</title>
<link>https://example.com/</link>
<description>What you write about</description>
<language>en</language>
<item>
<title>My first post</title>
<link>https://example.com/first-post</link>
<guid isPermaLink="true">https://example.com/first-post</guid>
<pubDate>Mon, 27 Jul 2026 09:00:00 +0000</pubDate>
<description>A sentence or two, or the whole post.</description>
</item>
</channel>
</rss>
<pubDate> is RFC 822, which is the one format people get wrong;
date -R prints it. A feed with a valid channel and no items at all is
fine by us — you can add the feed before you have posts.
Read, fix, verify, submit
Test your page without listing it — the second button on the form runs exactly the same checks and stores nothing. Then submit for real.