Skip to navigation Skip to main content
11ty Logo Sustainability Fundraising
Eleventy
Eleventy Documentation
Stable
2.0.1
Canary
3.0.0-alpha.16
Toggle Menu
Eleventy 1.93s
Gatsby 29.05s

RSS Plugin

Contents

A pack of plugins for generating an RSS (or Atom or JSON) feed using the Nunjucks templating syntax.

This plugin has a few excellent features:

Starting with RSS Plugin v2.0 and newer, there are two options to create feeds in your project using this plugin:

  1. Using a virtual template to create a feed with a few lines of configuration (easier, more abstracted).
  2. Using a manual template, adding configuration and a template file (more setup, but more control).

Installation Jump to heading

Available on npm.

npm install @11ty/eleventy-plugin-rss

Virtual Template Jump to heading

Pre-release only: v3.0.0-alpha.13Added in RSS 2.0.0 This method creates a feed template directly from your plugin configuration, without requiring additional files in your project.

ESM CommonJS
Filename .eleventy.js
import { feedPlugin } from "@11ty/eleventy-plugin-rss";

export default function (eleventyConfig) {
eleventyConfig.addPlugin(feedPlugin, {
type: "atom", // or "rss", "json"
outputPath: "/feed.xml",
collection: {
name: "posts", // iterate over `collections.posts`
limit: 10, // 0 means no limit
},
metadata: {
language: "en",
title: "Blog Title",
subtitle: "This is a longer description about your blog.",
base: "https://example.com/",
author: {
name: "Your Name",
email: "", // Optional
}
}
});
};
Filename .eleventy.js
const { feedPlugin } = require("@11ty/eleventy-plugin-rss");

// If you already have a configuration file make sure you don’t end
// up with multiple `module.exports =` in the same file!
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(feedPlugin, {
type: "atom", // or "rss", "json"
outputPath: "/feed.xml",
collection: {
name: "posts", // iterate over `collections.posts`
limit: 10, // 0 means no limit
},
metadata: {
language: "en",
title: "Blog Title",
subtitle: "This is a longer description about your blog.",
base: "https://example.com/",
author: {
name: "Your Name",
email: "", // Optional
}
}
});
};

This configuration is the only step you need. If you need additional control over the template output, you can use the Manual Template method.

Expand for full options list
  • type: (required) One of "atom" (default), "rss", or "json"
  • outputPath: (required, default: /feed.xml) Where to write the template in the output directory.
  • inputPath: (optional, default based on metadata.title) Change where the virtual template pretends to live on the file system (e.g. if you want project directory data files to apply via the Data Cascade)
  • collection.name: Collection entries to iterate over to populate your feed (e.g. name: "posts" for collections.posts)
  • collection.limit: Number of entries to include (0 means no limit).
  • metadata: Content used to populate the feed boilerplate.
  • stylesheet: URL to an XSL stylesheet to change how the feed is rendered in the browser (only for Atom and RSS feeds).
  • templateData, defaults to {}: Additional data to apply to the template (e.g. to add your feed to the Navigation plugin)

Manual Template Jump to heading

Configuration Jump to heading

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

ESM CommonJS
Filename .eleventy.js
import pluginRss from "@11ty/eleventy-plugin-rss";

export default function (eleventyConfig) {
eleventyConfig.addPlugin(pluginRss);
};
Filename .eleventy.js
const pluginRss = require("@11ty/eleventy-plugin-rss");

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

Added in RSS 1.1.0 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

Less Important Filters Jump to heading

Use with other template languages Jump to heading

Added in RSS 1.1.0 This plugin exports dateToRfc3339, dateToRfc822 (Added 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);
};
INFO:
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).

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.

INFO:
The following feed samples require RSS Plugin v2.0 or newer. Samples for RSS Plugin v1 are available on older versions of the docs.

Atom RSS JSON
---json
{
"permalink": "feed.xml",
"eleventyExcludeFromCollections": true,
"metadata": {
"title": "My Blog about Boats",
"description": "I am writing about my experiences as a naval navel-gazer.",
"language": "en",
"base": "https://example.com/",
"author": {
"name": "Boaty McBoatFace"
}
}
}
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ metadata.language or page.lang }}">
<title>{{ metadata.title }}</title>
<subtitle>{{ metadata.description }}</subtitle>
<link href="{{ permalink | htmlBaseUrl(metadata.base) }}" rel="self" />
<link href="{{ metadata.base | addPathPrefixToFullUrl }}" />
<updated>{{ collections.posts | getNewestCollectionItemDate | dateToRfc3339 }}</updated>
<id>{{ metadata.base | addPathPrefixToFullUrl }}</id>
<author>
<name>{{ metadata.author.name }}</name>
</author>
{%- for post in collections.posts | reverse %}
{%- set absolutePostUrl %}{{ post.url | htmlBaseUrl(metadata.base) }}{% endset %}
<entry>
<title>{{ post.data.title }}</title>
<link href="{{ absolutePostUrl }}" />
<updated>{{ post.date | dateToRfc3339 }}</updated>
<id>{{ absolutePostUrl }}</id>
<content type="html">{{ post.content | renderTransforms(post.data.page, metadata.base) }}</content>
</entry>
{%- endfor %}
</feed>
---json
{
"permalink": "feed.xml",
"eleventyExcludeFromCollections": true,
"metadata": {
"title": "My Blog about Boats",
"description": "I am writing about my experiences as a naval navel-gazer.",
"language": "en",
"base": "https://example.com/",
"author": {
"name": "Boaty McBoatFace"
}
}
}
---
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="{{ metadata.base | addPathPrefixToFullUrl }}" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ metadata.title }}</title>
<link>{{ metadata.base | addPathPrefixToFullUrl }}</link>
<atom:link href="{{ permalink | htmlBaseUrl(metadata.base) }}" rel="self" type="application/rss+xml" />
<description>{{ metadata.description }}</description>
<language>{{ metadata.language or page.lang }}</language>
{%- for post in collections.posts | reverse %}
{%- set absolutePostUrl = post.url | htmlBaseUrl(metadata.base) %}
<item>
<title>{{ post.data.title }}</title>
<link>{{ absolutePostUrl }}</link>
<description>{{ post.content | renderTransforms(post.data.page, metadata.base) }}</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",
"description": "I am writing about my experiences as a naval navel-gazer.",
"language": "en",
"base": "https://example.com/",
"author": {
"name": "Boaty McBoatFace"
}
}
}
---
{
"version": "https://jsonfeed.org/version/1.1",
"title": "{{ metadata.title }}",
"language": "{{ metadata.language or page.lang }}",
"home_page_url": "{{ metadata.base | addPathPrefixToFullUrl }}",
"feed_url": "{{ permalink | htmlBaseUrl(metadata.base) }}",
"description": "{{ metadata.description }}",
"authors": [
{
"name": "{{ metadata.author.name }}"
}
],
"items": [
{%- for post in collections.posts | reverse %}
{%- set absolutePostUrl %}{{ post.url | htmlBaseUrl(metadata.base) }}{% endset %}
{
"id": "{{ absolutePostUrl }}",
"url": "{{ absolutePostUrl }}",
"title": "{{ post.data.title }}",
"content_html": {% if post.content %}{{ post.content | renderTransforms(post.data.page, metadata.base) | dump | safe }}{% else %}""{% endif %},
"date_published": "{{ post.date | dateToRfc3339 }}"
}
{% if not loop.last %},{% endif %}
{%- endfor %}
]
}

Place the file in your input directory (and give it a .njk extension). For example: src/feed.njk or src/feed.json. If your input directory is src, the file 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 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)

Community Plugins Jump to heading


Other pages in Official Plugins: