Is your feature request related to a problem? Please describe.
Email addresses displayed on AstroPaper sites (e.g. in the social links) are exposed as plain text in the HTML source. Spam bots can easily scrape them, leading to unwanted spam for site owners.
Describe the solution you'd like
A built-in email obfuscation mechanism using XOR encoding — the same technique Cloudflare uses for its Email Address Obfuscation feature. It would work in three parts:
- A utility function that XOR-encodes the email at build time into a hex string (random key + encoded characters)
- A rehype plugin that automatically transforms
mailto: links in Markdown content — replacing the href with # and storing the encoded email in a data-encoded-email attribute
- A small inline client-side script (~15 lines) that decodes and restores the
mailto: links on page load
This way, the raw email never appears in the static HTML. Only users with JavaScript enabled (i.e. real visitors, not most bots) can see and click the email link.
Describe alternatives you've considered
- HTML entities encoding (
mai...): too weak — most HTML parsers decode them automatically, so bots can still read the email
- CSS
direction: rtl with reversed text: breaks copy-paste and accessibility, and doesn't protect the href attribute
- Rendering email as an image: not clickable, not accessible, poor UX
- Contact form instead of email link: effective but out of scope for a static template and requires a backend service
XOR encoding offers the best trade-off between protection, simplicity, and user experience.
Additional context
I have implemented this approach on my own AstroPaper-based site and it works well. The implementation is lightweight and non-breaking. Cloudflare's production use of the same technique validates its effectiveness against the vast majority of email scrapers.
A reference implementation could include:
- An
encodeEmail() utility for build-time encoding
- A
rehypeObfuscateEmail plugin for automatic Markdown mailto: link transformation
- An
ObfuscatedMailLink Astro component for use in templates (e.g. Socials.astro)
- A decoder script in the base layout
I'd be happy to open a PR with this implementation if there's interest.
Is your feature request related to a problem? Please describe.
Email addresses displayed on AstroPaper sites (e.g. in the social links) are exposed as plain text in the HTML source. Spam bots can easily scrape them, leading to unwanted spam for site owners.
Describe the solution you'd like
A built-in email obfuscation mechanism using XOR encoding — the same technique Cloudflare uses for its Email Address Obfuscation feature. It would work in three parts:
mailto:links in Markdown content — replacing thehrefwith#and storing the encoded email in adata-encoded-emailattributemailto:links on page loadThis way, the raw email never appears in the static HTML. Only users with JavaScript enabled (i.e. real visitors, not most bots) can see and click the email link.
Describe alternatives you've considered
mai...): too weak — most HTML parsers decode them automatically, so bots can still read the emaildirection: rtlwith reversed text: breaks copy-paste and accessibility, and doesn't protect thehrefattributeXOR encoding offers the best trade-off between protection, simplicity, and user experience.
Additional context
I have implemented this approach on my own AstroPaper-based site and it works well. The implementation is lightweight and non-breaking. Cloudflare's production use of the same technique validates its effectiveness against the vast majority of email scrapers.
A reference implementation could include:
encodeEmail()utility for build-time encodingrehypeObfuscateEmailplugin for automatic Markdownmailto:link transformationObfuscatedMailLinkAstro component for use in templates (e.g.Socials.astro)I'd be happy to open a PR with this implementation if there's interest.