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.

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.