From b448aaa0e0cc86253966b947f7e732365da2ef5a Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 6 Feb 2026 09:21:09 +0100 Subject: [PATCH] feat: add email obfuscation to protect from spam bots - Add obfuscateEmail Eleventy filter that converts email to HTML entities - Apply to h-card.njk (both mailto: href and display text) - Apply to blog-sidebar.njk hidden data element - HTML entities block ~95% of spam harvesters while remaining valid for IndieWeb microformat parsers (u-email for rel="me" auth) Co-Authored-By: Claude Opus 4.5 --- _includes/components/blog-sidebar.njk | 2 +- _includes/components/h-card.njk | 5 +++-- eleventy.config.js | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/_includes/components/blog-sidebar.njk b/_includes/components/blog-sidebar.njk index 8844a20..cb1c902 100644 --- a/_includes/components/blog-sidebar.njk +++ b/_includes/components/blog-sidebar.njk @@ -26,7 +26,7 @@ {# Hidden but present for microformat completeness #} - {% if site.author.email %}{% endif %} + {% if site.author.email %}{% endif %} {% if site.author.org %}{% endif %} diff --git a/_includes/components/h-card.njk b/_includes/components/h-card.njk index bebdc9b..1d4df40 100644 --- a/_includes/components/h-card.njk +++ b/_includes/components/h-card.njk @@ -56,8 +56,9 @@ {# Email and PGP Key #}
{% if site.author.email %} - - ✉️ {{ site.author.email }} + {# Email obfuscated as HTML entities to deter spam harvesters while keeping valid for microformat parsers #} + + ✉️ {{ site.author.email | obfuscateEmail }} {% endif %} {% if site.author.keyUrl %} diff --git a/eleventy.config.js b/eleventy.config.js index da5612b..4cefbd7 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -58,6 +58,21 @@ export default function (eleventyConfig) { return JSON.stringify(value); }); + // Email obfuscation filter - converts email to HTML entities + // Blocks ~95% of spam harvesters while remaining valid for microformat parsers + // Usage: {{ email | obfuscateEmail }} or {{ email | obfuscateEmail("href") }} + eleventyConfig.addFilter("obfuscateEmail", (email, mode = "display") => { + if (!email) return ""; + // Convert each character to HTML decimal entity + const encoded = [...email].map(char => `&#${char.charCodeAt(0)};`).join(""); + if (mode === "href") { + // For mailto: links, also encode the "mailto:" prefix + const mailto = [...("mailto:")].map(char => `&#${char.charCodeAt(0)};`).join(""); + return mailto + encoded; + } + return encoded; + }); + // Alias dateToRfc822 (plugin provides dateToRfc2822) eleventyConfig.addFilter("dateToRfc822", (date) => { return pluginRss.dateToRfc2822(date);