> ## Content Index
> Fetch the complete content index at: https://www.autodidacts.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# Create custom filtered RSS feeds in Ghost, the easy way
- URL: https://www.autodidacts.io/create-custom-filtered-rss-feeds-with-ghost-cms-routes-channels/
- Published: 2026-01-08T00:09:22.000Z
- Updated: 2026-01-08T00:09:22.000Z
- Description: Create custom feeds, on custom routes, without editing theme files
- Author: Curiositry
- Tags: 100DaysToOffload, RSS, Ghost, Tutorial

****Note:** this post is part of [#100DaysToOffload](https://100daystooffload.com/?ref=autodidacts.io), a challenge to publish 100 posts in 365 days. These posts are generally shorter and less polished than our normal posts; expect typos and unfiltered thoughts! [View more posts in this series.](https://www.autodidacts.io/tag/100daystooffload/)

  
When [I started 100 days to offload](https://www.autodidacts.io/100daystooffload/), and mentioned that readers could [filter out posts by tag in their feed reader](https://www.autodidacts.io/filter-rss-feeds-by-tag/), an RSS subscriber wrote in suggesting that I create custom feeds instead. That way, readers could keep the longform posts in their [read-every-post feed](https://bojidar-bg.dev/blog/2025-10-26-sorting-feeds/?ref=autodidacts.io), while relegating the firehose RSS feed to a lower-priority section of their inbox.

I have now done this. Here is the feed for everything *other* than #100DaysToOffload posts:

<https://www.autodidacts.io/filter-100daystooffload/rss/> (I may not maintain this route after I finish the challenge, so you’ll want to switch back to <https://www.autodidacts.io/rss/> (the everything feed) at that point.)

<https://www.autodidacts.io/rss/> is everything.

<https://www.autodidacts.io/tag/100daystooffload/rss/> is *just* #100DaysToOffload posts.

---

**First, I did it the hard way.** After reading [on the forum](https://forum.ghost.org/t/configuring-custom-rss-feeds-when-using-a-custom-page/44460?ref=autodidacts.io) and [the](https://ghost.org/tutorials/custom-rss-feed/?ref=autodidacts.io) [docs](https://ghost.org/integrations/custom-rss/?ref=autodidacts.io), I used `routes.yaml` and a custom `rss.hbs` in the root directory of my theme.

I added the following to `routes.yaml`:

```yaml
routes:
  /filter-100daystooffload/rss/:
    template: rss
    content_type: text/xml

```

And added an `rss.hbs` template with the following contents:

```xml
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<title><![CDATA[ {{@site.title}} ]]></title>
<description><![CDATA[ {{@site.description}} ]]></description>
<link>{{@site.url}}</link>
<image>
    <url>{{@site.url}}/favicon.png</url>
    <title>{{@site.title}}</title>
    <link>{{@site.url}}</link>
</image>
<lastBuildDate>{{date format="ddd, DD MMM YYYY HH:mm:ss ZZ"}}</lastBuildDate>
<atom:link href="{{@site.url}}" rel="self" type="application/rss+xml"/
<ttl>60</ttl>
{{#get "posts" limit="100" filter="tags:-100daystooffload" include="authors,tags"}}
    {{#foreach posts}}
    <item>
        <title><![CDATA[ {{title}} ]]></title>
        <description><![CDATA[ {{excerpt}} ]]></description>
        <link>{{url absolute="true"}}</link>
        <guid isPermaLink="false">{{id}}</guid>
        <category><![CDATA[ {{primary_tag.name}} ]]></category>
        <dc:creator><![CDATA[ {{primary_author.name}} ]]></dc:creator>
        <pubDate>{{date format="ddd, DD MMM YYYY HH:mm:ss ZZ"}}</pubDate>
        <media:content url="{{feature_image}}" medium="image"/
        <content:encoded><![CDATA[ {{content}} ]]></content:encoded>
    </item>
    {{/foreach}}
{{/get}}

</channel>
</rss>

```

The only line I had to change, depending on what we want to filter out, was this:

```
{{#get "posts" limit="100" filter="tags:-100daystooffload" include="authors,tags"}}

```

(Note: `limit=”all”` is unfortunately depreciated. But feed readers hit /rss endpoints frequently, and lowering the limit reduces server load, so it’s not a huge deal.)

Note, also, that the default RSS feeds are generated with code: there’s no `rss.hbs` in Ghost core that I could copy. This version has a few small differences from the default RSS template, but works fine.

---

**I didn’t like this approach,** for several reasons. Mainly, the filter is hardcoded, so the template can’t be re-used for multiple custom feeds. And if Ghost updates the default template when a new version of the RSS spec comes out in 2200 AD, this will still be RSS 2.0\. It feels *janky*.

I tried using a collection, but that didn’t work. But, lo! [Channels have RSS feeds by default](https://docs.ghost.org/themes/routing?ref=autodidacts.io#filtering-collections:~:text=These%20are,feed), and can be filtered!

In the end, all that was needed was the following in my `routes.yaml`:

```yaml
routes:
  /filter-100daystooffload/:
    controller: channel
    filter: tag:-[100daystooffload]

```

And as a bonus (assuming you want it), there’s a homepage view as well as the RSS feed.

Along the way, before hitting on this 4-lines-of-text solution, I managed to create the world’s *least* valid `text/xml` RSS feed — the “everything everywhere all at once” edition — with every piece of custom CSS and JS from every post applied at once, including typesetting the whole thing in Comic Sans. It was glorious.

![](https://www.autodidacts.io/content/images/2026/01/invalid-rss-feed-2.png)