mailhider
A ~1 KB JavaScript library that hides email addresses in your HTML source so scrapers can’t extract them, while still rendering a working mailto: link for humans. Below are the three modes, running live on this page.
GitHub
·
npm
·
npm i mailhider
1. Baseline — a plain mailto: link scrapeable
The control. A normal contact link, exactly the kind a scraper will harvest.
<a href="mailto:plain@example.com">plain@example.com</a>2. Reverse mode default
The username and domain are stored reversed in data-* attributes. A tiny runtime reverses them on page load and writes a real mailto: anchor. A regex over the HTML source finds nothing.
<span class="mh-email" data-u="olleh" data-d="moc.elpmaxe"> <noscript>Enable JavaScript to view email.</noscript> </span>
3. Click-to-reveal mode defeats headless browsers
The email isn’t assembled until the visitor clicks. This defeats non-interactive JS-running scrapers (headless Chrome, Playwright) because they don’t simulate clicks on every span on every page they crawl. A scraper that does click every span on every page can still extract it.
<span class="mh-email" data-u="kcilc" data-d="moc.elpmaxe" data-mh-mode="click"> Show email </span>
4. Bracket fallback weakest
For visitors with JavaScript disabled. The text reads user[at]domain[dot]tld. Scrapers that match [at]/[dot] patterns will still extract this, so it’s only worth using if no-JS reachability matters to you.
What just happened
This page ran a regex over its own HTML source (the bytes the server sent — not the DOM after JavaScript decoded it) and looked for any string matching an email. The results above show what a typical scraper sees.
The reverse and click modes leak nothing. The baseline link and the bracket fallback leak. Pick your trade-off.
Use it
Three ways, depending on whether you have a build step.
No build — drop into any HTML page:
<span class="mh-email" data-u="olleh" data-d="moc.elpmaxe"></span> <script src="https://unpkg.com/mailhider/dist/browser.js"></script>
Build-time encoding (Node):
import { obfuscate } from 'mailhider';
const html = obfuscate('hello@example.com', { mode: 'click' });
CLI:
npx mailhider hello@example.com --mode=click