Adding Excerpts to an 11ty RSS Feed

I previously wrote about creating multiple feeds with the 11ty RSS Plugin which I was doing in service of creating a feed for Planet Drupal. While creating a second feed was an important first step, I also found that my feed needed to have an excerpt of a specific maximum length.

There are a handful of options out there for handling excerpts with 11ty. eleventy-plugin-excerpt adds a universal shortcode for excerpts. This was close to what I needed, but the shortcode takes the entire template object as an input, which made using additional filters like htmlToAbsoluteUrls from eleventy-rss difficult.

Slightly buried in the docs to customize front matter parsing is an example of parsing excerpts from content using additional options from the gray-matter package. I was only able to access the excerpt in my feed if I used an excerpt alias for some reason, so I ended up adding the following to my 11ty config:

  excerpt: true,
  excerpt_alias: 'feed_excerpt'

I can now include a separator in my post markdown as follows:

This will serve as my excerpt. It is also included in the full post.
And everything after will also be included in the full post, but not the excerpt.

It is also possible to manually overwrite the excerpt field by specifying it in your markdown front matter. This nice little escape hatch comes in handy if you want the excerpt to combine non sequential parts of the post, or otherwise work around some markup that should be excluded from the excerpt.

Since these excerpts were being added for an RSS feed, I also needed to take an extra step to ensure that the excerpt was being rendered as markup rather than raw markdown. As a quick workaround, I created a custom feedEncode filter using 11ty’s default markdown parsing library:

// eleventy.js
const md = require('markdown-it')();

// add within module.exports function:
eleventyConfig.addNunjucksFilter("feedEncode", function(value) {
  return value ? md.render(value) : '';

Then in my feed template, I can pass the excerpt through my filter to ensure it will be rendered as html in feed readers:

{{ | htmlToAbsoluteUrls(absolutePostUrl) | feedEncode }}

Due to some confusion related to feed validation, I also created an RSS feed example for the 11ty RSS plugin. In hindsight, I could have gotten away with the default Atom feed example, but perhaps someone else out there will find this useful.