Stand with Ukraine 🇺🇦
Eleventy
The possum is Eleventy’s mascot

Eleventy Documentation

Menu

RSS Plugin Jump to heading

A pack of plugins for generating an RSS feed (actually an Atom feed, but who’s counting) using the Nunjucks templating engine.

Template Compatibility Jump to heading

Installation Jump to heading

Available on npm.

npm install @11ty/eleventy-plugin-rss --save-dev

Open up your Eleventy config file (probably .eleventy.js) and use addPlugin:

Filename .eleventy.js
const pluginRss = require("@11ty/eleventy-plugin-rss");

module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(pluginRss);
};
You’re only allowed one module.exports in your configuration file, so make sure you only copy the require and the addPlugin lines above!

Options New in RSS 1.1.0 Jump to heading

Advanced control of PostHTML rendering options via posthtmlRenderOptions.

const pluginRss = require("@11ty/eleventy-plugin-rss");

module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(pluginRss, {
posthtmlRenderOptions: {
closingSingleTag: "default" // opt-out of <img/>-style XHTML single tags
}
});
};

Supplies the following Nunjucks Filters Jump to heading

Use with other template languages New in RSS 1.1.0 Jump to heading

This plugin exports dateToRfc3339, dateToRfc822 (New in RSS 1.2.0), getNewestCollectionItemDate, absoluteUrl, and convertHtmlToAbsoluteUrls functions so you can use with your own filters. For example:

const pluginRss = require("@11ty/eleventy-plugin-rss");

module.exports = function(eleventyConfig) {
eleventyConfig.addLiquidFilter("dateToRfc3339", pluginRss.dateToRfc3339);

// New in RSS 1.2.0
eleventyConfig.addLiquidFilter("dateToRfc822", pluginRss.dateToRfc822);
};
Do keep in mind that escaping HTML content is a feature provided as part of Nunjucks. Moving to another template language may require a different option for escaping (for example, html-entities).

Deprecated Filters Jump to heading

Sample Feed templates Jump to heading

Copy and paste this template and modify the JSON metadata to match your feed’s needs. Make sure collections.posts matches the template collection you want to provide a feed for.

View this example in: Atom RSS JSON
---json
{
"permalink": "feed.xml",
"eleventyExcludeFromCollections": true,
"metadata": {
"title": "My Blog about Boats",
"subtitle": "I am writing about my experiences as a naval navel-gazer.",
"url": "https://example.com/",
"feedUrl": "https://example.com/feed.xml",
"author": {
"name": "Boaty McBoatFace",
"email": "me@example.com"
}
}
}
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>{{ metadata.title }}</title>
<subtitle>{{ metadata.subtitle }}</subtitle>
<link href="{{ metadata.feedUrl }}" rel="self"/>
<link href="{{ metadata.url }}"/>
<updated>{{ collections.posts | getNewestCollectionItemDate | dateToRfc3339 }}</updated>
<id>{{ metadata.url }}</id>
<author>
<name>{{ metadata.author.name }}</name>
<email>{{ metadata.author.email }}</email>
</author>
{%- for post in collections.posts %}
{% set absolutePostUrl %}{{ post.url | url | absoluteUrl(metadata.url) }}{% endset %}
<entry>
<title>{{ post.data.title }}</title>
<link href="{{ absolutePostUrl }}"/>
<updated>{{ post.date | dateToRfc3339 }}</updated>
<id>{{ absolutePostUrl }}</id>
<content type="html">{{ post.templateContent | htmlToAbsoluteUrls(absolutePostUrl) }}</content>
</entry>
{%- endfor %}
</feed>
---json
{
"permalink": "feed.xml",
"eleventyExcludeFromCollections": true,
"metadata": {
"title": "My Blog about Boats",
"subtitle": "I am writing about my experiences as a naval navel-gazer.",
"url": "https://example.com/",
"feedUrl": "https://example.com/feed.xml",
"author": {
"name": "Boaty McBoatFace",
"email": "me@example.com"
}
}
}
---
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="{{ metadata.url }}">
<channel>
<title>{{ metadata.title }}</title>
<link>{{ metadata.url }}</link>
<description>{{ metadata.subtitle }}</description>
<language>en</language>
{%- for post in collections.posts | reverse %}
{% set absolutePostUrl %}{{ post.url | url | absoluteUrl(metadata.url) }}{% endset %}
<item>
<title>{{ post.data.title }}</title>
<link>{{ absolutePostUrl }}</link>
<description>{{ post.templateContent | htmlToAbsoluteUrls(absolutePostUrl) }}</description>
<pubDate>{{ post.date | dateToRfc822 }}</pubDate>
<dc:creator>{{ metadata.author.name }}</dc:creator>
<guid>{{ absolutePostUrl }}</guid>
</item>
{%- endfor %}
</channel>
</rss>
---json
{
"permalink": "feed.json",
"eleventyExcludeFromCollections": true,
"metadata": {
"title": "My Blog about Boats",
"subtitle": "I am writing about my experiences as a naval navel-gazer.",
"url": "https://example.com/",
"feedUrl": "https://example.com/feed.json",
"author": {
"name": "Boaty McBoatFace",
"url": "https://example.com/about-boaty/"
}
}
}
---
{
"version": "https://jsonfeed.org/version/1",
"title": "{{ metadata.title }}",
"home_page_url": "{{ metadata.url }}",
"feed_url": "{{ metadata.feedUrl }}",
"description": "{{ metadata.subtitle }}",
"author": {
"name": "{{ metadata.author.name }}",
"url": "{{ metadata.author.url }}"
},
"items": [
{%- for post in collections.posts | reverse %}
{%- set absolutePostUrl %}{{ post.url | url | absoluteUrl(metadata.url) }}{% endset -%}
{
"id": "{{ absolutePostUrl }}",
"url": "{{ absolutePostUrl }}",
"title": "{{ post.data.title }}",
"content_html": {% if post.templateContent %}{{ post.templateContent | dump | safe }}{% else %}""{% endif %},
"date_published": "{{ post.date | dateToRfc3339 }}"
}
{% if not loop.last %},{% endif %}
{%- endfor %}
]
}

Place the file anywhere in your project (give it a .njk extension) and it will be transformed into a feed.xml (or feed.json if you’re using the JSON variant) file at the root of your website when Eleventy builds it. It can then be useful to check the file against a feed validator, such as the W3C Feed Validation Service to make sure that the output was good.

Ultimately your feed will be available at https://yourwebsite.com/feed.xml (or https://yourwebsite.com/feed.json)


Other pages in Plugins: