--- author: "Chris Burnell" title: "eleventy-cache-webmentions" source: https://chrisburnell.com/eleventy-cache-webmentions/ clipped: 2024-06-25 published: 2022-01-15 topics: tags: [clipping] --- # eleventy-cache-webmentions Cache webmentions using eleventy-fetch and make them available to use in collections, layouts, pages, etc. in Eleventy. There are 21 stargazers [on GitHub](https://github.com/chrisburnell/eleventy-cache-webmentions) and it has over 9,150 downloads [on npm](https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions). ![A hand with a tattoo reading, “Cache up Sucker” with a dollar sign in the middle](https://chrisburnell.com/images/built/eleventy-cache-webmentions-395.png "A hand with a tattoo reading, “Cache up Sucker” with a dollar sign in the middle") [![eleventy-cache-webmentions on GitHub](https://img.shields.io/static/v1?label=chrisburnell&message=eleventy-cache-webmentions&color=5f8aa6&logo=github)](https://github.com/chrisburnell/eleventy-cache-webmentions "Go to Repository: @chrisburnell/eleventy-cache-webmentions") [![eleventy-cache-webmentions Releases](https://img.shields.io/github/release/chrisburnell/eleventy-cache-webmentions?include_prereleases=&sort=semver&color=5f8aa6)](https://github.com/chrisburnell/eleventy-cache-webmentions/releases "Go to Releases: @chrisburnell/eleventy-cache-webmentions") [![eleventy-cache-webmentions License](https://img.shields.io/badge/License-MIT-5f8aa6)](https://github.com/chrisburnell/eleventy-cache-webmentions/blob/main/LICENSE "Go to License: @chrisburnell/eleventy-cache-webmentions") Breaking changes for v2.0.0! Version 2.0.0 introduces a breaking change for those migrating from earlier versions of the plugin. This affects usage of the plugin from JavaScript files; specifically, you will need to make a small change to the way that you `require()` the plugin by removing an extra set of parentheses: **v1.2.5 and below** ``` require("@chrisburnell/eleventy-cache-webmentions")() ``` **v2.0.0 and above** ``` require("@chrisburnell/eleventy-cache-webmentions") ``` ## Installation [Permalink ¶](#installation "Permalink for Installation") [Available on npm](https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions): ``` npm install @chrisburnell/eleventy-cache-webmentions --save-dev ``` You can also download it directly [from GitHub](https://github.com/chrisburnell/eleventy-cache-webmentions): [https://github.com/chrisburnell/eleventy-cache-webmentions/archive/main.zip](https://github.com/chrisburnell/eleventy-cache-webmentions/archive/main.zip) Inside your Eleventy config file, use `addPlugin()` to add it to your project: ``` const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions") module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(pluginWebmentions, { domain: "https://example.com", feed: "https://webmentions.example.com?token=S3cr3tT0k3n", key: "array_of_webmentions" }) } ``` Full options list ``` const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions") module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(pluginWebmentions, { domain: "https://example.com", feed: "https://webmentions.example.com?token=S3cr3tT0k3n", key: "array_of_webmentions", directory: ".cache", duration: "1d", uniqueKey: "webmentions", allowedHTML: { allowedTags: ["b", "i", "em", "strong", "a"], allowedAttributes: { a: ["href"], }, }, allowlist: [], blocklist: [], urlReplacements: {}, maximumHtmlLength: 2000, maximumHtmlText: "mentioned this in", }) } ``` ## Usage [Permalink ¶](#usage "Permalink for Usage") `eleventy-cache-webmentions` comes with a number of ways of accessing your Webmentions as [Global Data](https://www.11ty.dev/docs/data-global-custom/) in both JavaScript and Liquid/Nunjucks as well as a series of [Eleventy Filters](https://www.11ty.dev/docs/filters/) and JavaScript Functions for filtering, sorting, and reading properties about each Webmention: ### Global Data JavaScript ``` const { defaults, webmentionsByUrl, } = require("@chrisburnell/eleventy-cache-webmentions") ``` Liquid / Nunjucks ``` {{ webmentionsDefaults }} {{ webmentionsByUrl }} ``` ### Filters JavaScript ``` const { getWebmentions, getWebmentionsByTypes, getWebmentionPublished, getWebmentionContent, getWebmentionSource, getWebmentionTarget, getWebmentionType, } = require("@chrisburnell/eleventy-cache-webmentions") const webmentions = getWebmentions({ domain: "https://example.com", feed: "https://webmentions.example.com?token=S3cr3tT0k3n", key: "array_of_webmentions" }, "https://example.com/specific-page/") const responsesOnly = getWebmentionsByTypes(webmentions, ['mention-of', 'in-reply-to']) webmentions.forEach((webmention) => { const published = getWebmentionPublished(webmention) const content = getWebmentionContent(webmention) const source = getWebmentionSource(webmention) const target = getWebmentionTarget(webmention) const type = getWebmentionType(webmention) }) ``` Liquid / Nunjucks ``` {% set webmentions = ('https://example.com' + page.url) | getWebmentions %} {{ set responses = webmentions | getWebmentionsByTypes(['mention-of', 'in-reply-to']) }} {% for webmention in webmentions %} {{ webmentions | getWebmentionPublished }} {{ webmentions | getWebmentionContent }} {{ webmentions | getWebmentionSource }} {{ webmentions | getWebmentionTarget }} {{ webmentions | getWebmentionType }} {% endfor %} ``` ## Attach Webmentions to Pages using Directory Data [Permalink ¶](#attach-webmentions "Permalink for Attach Webmentions to Pages using Directory Data") Using [Eleventy’s Data Cascade](https://www.11ty.dev/docs/data-cascade/), you can attach Webmentions to each page by using [Directory Specific Data Files](https://www.11ty.dev/docs/data-template-dir/). For example, if you have a folder, `/pages/`, and want to attach Webmentions to each page, create or add the following to a `pages.11tydata.js` file within the folder: ``` const { getWebmentions, getPublished } = require("@chrisburnell/eleventy-cache-webmentions") module.exports = { eleventyComputed: { webmentions: (data) => { const webmentionsForUrl = getWebmentions({ domain: "https://example.com", feed: "https://webmentions.example.com?token=S3cr3tT0k3n", key: "array_of_webmentions" }, "https://example.com" + data.page.url) if (webmentionsForUrl.length) { return webmentionsForUrl.sort((a, b) => { return getPublished(b) - getPublished(a) }) } return [] }, }, } ``` This attaches an Array containing Webmentions to each page (based on its URL). You can then access this Array of Webmentions with the variable, webmentions, within a [Layout](https://www.11ty.dev/docs/layouts/), [Include](https://www.11ty.dev/docs/includes/), or from the page itself: ``` {% for webmention in webmentions %} {% endfor %} ``` These Arrays of Webmentions can even be accessed when building [Collections](https://www.11ty.dev/docs/collections/), allowing you to create a Collection of pages sorted by their number of Webmentions, for example: ``` module.exports = (eleventyConfig) => { eleventyConfig.addCollection("popular", (collection) => { return collection .sort((a, b) => { return b.data.webmentions.length - a.data.webmentions.length }) }) } ``` ## Without Directory Data [Permalink ¶](#without-directory-data "Permalink for Without Directory Data") If you would rather get Webmentions for a given page directly from a Layout/Include/Page itself, you can do so using the Filter, `getWebmentions`: ``` {% set webmentions = ('https://example.com' + page.url) | getWebmentions %} {% for webmention in webmentions %} ... {% endfor %} ``` ## Get specific types of Webmentions [Permalink ¶](#allowed-types "Permalink for Get specific types of Webmentions") Instead of getting all the Webmentions for a given page, you may want to grab only certain types of Webmentions. This is useful if you want to display different types of Webmentions separately, e.g.: ``` {% set bookmarks = webmentions | getWebmentionsByTypes(['bookmark-of']) %} {% set likes = webmentions | getWebmentionsByTypes(['like-of']) %} {% set reposts = webmentions | getWebmentionsByTypes(['repost-of']) %} {% set replies = webmentions | getWebmentionsByTypes(['mention-of', 'in-reply-to']) %} ``` ## Get all Webmentions at once [Permalink ¶](#all-webmentions "Permalink for Get all Webmentions at once") If you need it, the plugin also makes available an Object containing your cached Webmentions organised in key:value pairs, where each key is a full URL on your website and its value is an Array of Webmentions sent to that URL: ``` {% set count = 0 %} {% for url, array in webmentionsByUrl %} {% set count = array.length + count %} {% endfor %}

This website has received {{ count }} Webmentions!

``` ## Webmention.io [Permalink ¶](#webmention-io "Permalink for Webmention.io") [Webmention.io](https://webmention.io/) is a in-place Webmention receiver solution that you can use by authenticating yourself via [IndieAuth](https://indieauth.com/) (or host it yourself), and, like *so much* other publicly-available IndieWeb software, is built and hosted by [Aaron Parecki](https://aaronparecki.com/). ### Add your token Get set up on [Webmention.io](https://webmention.io/) and add your **API Key** (found on your [settings page](https://webmention.io/settings)) to your project as an environment variable, i.e. in a `.env` file in the root of your project: ``` WEBMENTION_IO_TOKEN=njJql0lKXnotreal4x3Wmd ``` ### Set your feed and key config options The example below requests the [JF2](https://www.w3.org/TR/jf2/) file format, which I highly recommend using; although, there is a JSON format available from [Webmention.io](https://webmention.io/) as well. The [official documentation](https://github.com/aaronpk/webmention.io) has more information on how to use these two formats. The key difference between the two feed formats is in the *naming* of the keys: the JF2 format holds the array of Webmentions in the `children` key, whereas the JSON format holds them in the `links` key. The JF2 format, however, provides keys and values that more tightly-align with [microformats](https://indieweb.org/microformats), the method I recommend the most for marking up HTML such that it can be consumed and understood by search engines, aggregators, and other tools across the IndieWeb. ``` const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions") module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(pluginWebmentions, { domain: "https://example.com", feed: `https://webmention.io/api/mentions.jf2?domain=example.com&per-page=9001&token=${process.env.WEBMENTION_IO_TOKEN}`, key: "children" }) } ``` If you want to use the JSON format instead, make sure that you replace `mentions.jf2` in the URL with `mentions.json` and change the value of the key from `children` to `links`. ## go-jamming [Permalink ¶](#go-jamming "Permalink for go-jamming") [go-jamming](https://git.brainbaking.com/wgroeneveld/go-jamming) is a self-hosted Webmention sender and receiver, built in Go by [Wouter Groeneveld](https://brainbaking.com/) and available with more information on his [personal git instance](https://git.brainbaking.com/wgroeneveld/go-jamming). ### Add your token Once you’ve set up your *go-jamming* server and you’ve defined your token, you’ll need add it to your project as an environment variable, i.e. in a `.env` file in the root of your project: ``` GO_JAMMING_TOKEN=njJql0lKXnotreal4x3Wmd ``` ### Set your feed and key config options ``` const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions") module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(pluginWebmentions, { domain: "https://example.com", feed: `https://jam.example.com/webmention/example.com/${process.env.GO_JAMMING_TOKEN}`, key: "json" }) } ```