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 <noreply@anthropic.com>
This commit is contained in:
Ricardo
2026-02-06 09:21:09 +01:00
parent f37cd3b913
commit b448aaa0e0
3 changed files with 19 additions and 3 deletions
+1 -1
View File
@@ -26,7 +26,7 @@
</div>
{# Hidden but present for microformat completeness #}
<p class="p-note hidden">{{ site.author.bio }}</p>
{% if site.author.email %}<data class="u-email hidden" value="{{ site.author.email }}"></data>{% endif %}
{% if site.author.email %}<data class="u-email hidden" value="{{ site.author.email | obfuscateEmail }}"></data>{% endif %}
{% if site.author.org %}<data class="p-org hidden" value="{{ site.author.org }}"></data>{% endif %}
</div>
+3 -2
View File
@@ -56,8 +56,9 @@
{# Email and PGP Key #}
<div class="mt-2 flex flex-wrap gap-3 text-sm">
{% if site.author.email %}
<a href="mailto:{{ site.author.email }}" class="u-email text-primary-600 dark:text-primary-400 hover:underline" itemprop="email">
✉️ {{ site.author.email }}
{# Email obfuscated as HTML entities to deter spam harvesters while keeping valid for microformat parsers #}
<a href="{{ site.author.email | obfuscateEmail('href') }}" class="u-email text-primary-600 dark:text-primary-400 hover:underline" itemprop="email">
✉️ {{ site.author.email | obfuscateEmail }}
</a>
{% endif %}
{% if site.author.keyUrl %}
+15
View File
@@ -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);