You can publish a contact email without getting scraped, but not by hiding it cleverly. The reliable approach is to stop putting a raw, harvestable address in the HTML at all: use a contact form as the primary route, and if you must show an address, show one that is disposable by design — a role address on your own domain, or a dedicated inbox you can rotate the moment it starts attracting junk. Encoding tricks such as @ or JavaScript assembly still defeat some naive bots, but they are speed bumps, not protection.
Why a plain address in HTML gets harvested
Email harvesting is one of the oldest automated annoyances on the web. A crawler fetches pages, runs a regular expression over the raw text, and collects anything shaped like an address. It does not need to understand your layout, and it does not care whether the address is in a mailto: link, a paragraph, or a footer.
What has changed is the volume and the economics. Harvesting is cheap, lists are traded freely, and a single address that reaches a few lists will keep receiving spam for years. The address does not have to be valuable on its own — it only has to be valid.
Two things follow from this. First, obfuscation is a filter, not a wall: it raises the cost of harvesting slightly, which pushes casual bots elsewhere but does nothing against a determined one. Second, the real defence is architectural — decide what an address is for, and make it replaceable.
Does obfuscating an email address still work?
Partly, and less each year. Here is an honest ranking of the common techniques, from weakest to strongest:
- Plain text or a
mailto:link. Harvested immediately. Nothing is gained. - Character entities such as
@for the at-sign, or splitting the address into spans. Defeats simple regexes that read the HTML source, but browsers render the address perfectly, so any bot that parses rendered text — or runs a headless browser — sees it anyway. - JavaScript assembly (building the address from array fragments and writing it into the DOM on click). More effective, because the address never appears in the served HTML. Costs you accessibility, breaks for users with scripts disabled, and complicates copying the address on mobile.
- CSS tricks such as
direction: rtlor reversed text. Fragile, confusing to screen readers, and easily normalised by a parser. - Text-as-image. Works against text scrapers, fails against OCR, and is hostile to screen readers and to anyone who wants to copy the address.
- Not publishing the address at all. The only approach that scales.
If you want a middle path, a common compromise is a short JavaScript snippet that assembles the address only when the visitor clicks a "Show email address" button. It keeps the address out of the page source for casual crawlers while remaining usable. Treat it as a courtesy to your inbox rather than a security control.
One warning worth stating plainly: do not put the address in a data- attribute, a hidden input, an HTML comment, or a JSON-LD block. Those are read by scrapers precisely because people assume they are invisible.
Contact form or mailto link: which should you use?
For most sites, a contact form is the better default. It keeps the address off the page entirely, lets you add a spam trap or rate limit, and gives you a record of the conversation. The trade-offs are real, though, and worth being honest about with your visitors.
| Approach | Harvesting risk | Friction for the sender | Notes |
|---|---|---|---|
| Contact form | Low — no address exposed | Medium; needs a working form and a reply address | Best default. Requires maintenance and a spam strategy of its own. |
mailto: link | High | Low if a mail client is configured, high if not | Many visitors on webmail or mobile have no handler set, so the link silently does nothing. |
| Address shown as text | High | Low; can be copied anywhere | Useful for people who want to keep a record outside your site. |
| Form plus a published role address | Medium | Low | A sensible combination for organisations that must be reachable by non-web channels. |
A form is not automatically safer. Forms attract their own abuse — automated submissions, link spam, and messages designed to look like support requests. Whatever you build, keep the form simple, validate on the server, and never let a submission trigger an automatic reply to an address the sender controls without some check.
If you do publish an address, publish it as text as well as a link. A mailto: link alone is unhelpful for anyone whose browser has no mail handler configured — a surprisingly common situation on shared and locked-down machines.
Use a role address you control, not your personal inbox
The single most effective habit is to separate the address you publish from the address you read. A role address — hello@, contact@, support@, press@ — on your own domain does three things a personal address cannot:
- It can be deleted and recreated without touching your identity or your account logins.
- It can be routed to a shared inbox, a ticket system, or a folder that someone else monitors.
- It makes it obvious to recipients that the address is a channel, not a person.
Role addresses are also heavily targeted, because they are predictable. A bot does not need to find contact@yourdomain on your site — it can simply guess it. That is an argument for publishing a less obvious address if you can, or for filtering aggressively at the mail server, rather than for leaving the address off your site entirely.
If you are running a small project and do not want to expose your main mailbox, a disposable inbox is a reasonable place to receive initial enquiries — but check the timer before you rely on it. MailboxTemp inboxes last 60 minutes by default and can be extended in ten-minute steps, so they suit a short window of contact rather than ongoing correspondence. For a permanent public channel, a role address on a domain you own is the right tool; the disposable inbox is for the trial run before you commit. Our guide to email aliases vs disposable email sets out where each one fits.
How to rotate an address once it starts getting spam
No published address stays clean forever. Plan for replacement from the start, so that the day it turns is an administrative task rather than an incident.
- Keep the old address alive for a while. Set an auto-reply explaining the new address, and keep it for at least a few months so that genuine contacts are not lost.
- Update every place the address appears. Footers, contact pages, invoice templates, social profiles, domain WHOIS records, app store listings, and printed material are the usual suspects.
- Watch what the old address receives. If it starts getting credential-phishing messages that reference your brand, that is a sign the list has been resold, not a sign you did something wrong.
- Do not reply to spam to "unsubscribe". For harvested lists, a reply mostly confirms the address is live. Our piece on stopping newsletter spam without unsubscribing covers the exceptions.
Where a disposable or temporary address fits — and where it does not
Disposable addresses are often suggested as a fix for contact-page harvesting. That is half right. They are excellent for a short-lived contact route: a launch page, a one-off event, a form you are testing. They are a poor fit for a permanent public contact channel, because the inbox expires and cannot be recovered afterwards.
Be clear about the limits before you publish one:
- Inboxes expire. Once gone, mail sent to that address is not delivered to you.
- Disposable domains are widely blocked by signup forms, and some mail filters treat them with suspicion.
- They are receive-only, so you cannot reply from the address itself.
That last point matters for a contact page: if someone writes to you, they expect a reply from the address they wrote to. A disposable inbox is a place to collect a first message, then continue the conversation from a real address. If you want to understand the mechanics, see what a disposable email is and whether a temp mail can be recovered.
What about privacy law and accessibility?
Two obligations are easy to overlook when you are focused on bots.
The first is accessibility. An address rendered as an image, or assembled by JavaScript on hover, may be unusable with a screen reader or a keyboard. If you obfuscate, provide a form as an alternative route and make the reveal control a real button with a clear label.
The second is data protection. A contact form collects personal data, and the rules that apply depend on where you and your visitors are. Neither UK GDPR nor the EU GDPR requires you to publish an email address, and both are compatible with using a form — provided you say what you do with the data and keep it to what you need.
Sources
- RFC 6068, The 'mailto' URI Scheme — the specification behind
mailto:links, including the header fields you can prefill: https://www.rfc-editor.org/rfc/rfc6068.html - RFC 6854, Update to Internet Message Format to Allow Group Syntax in the "From:" and "Sender:" Header Fields — part of the address syntax that scrapers try to match: https://www.rfc-editor.org/rfc/rfc6854.html
- W3C Web Content Accessibility Guidelines (WCAG) 2.2 — relevant to any obfuscation technique that affects readability or keyboard access: https://www.w3.org/TR/WCAG22/
What to do
- Make a contact form the primary route, and keep the form short enough that people actually use it.
- If you must publish an address, publish a role address on a domain you control — never your personal mailbox.
- Show the address as text as well as a
mailto:link, so it works without a configured mail client. - Use JavaScript assembly or entity encoding only as a light deterrent, and never hide an address in attributes, comments or structured data.
- Decide in advance how you will rotate the address, and keep the old one alive with an auto-reply for a few months.
- Reserve disposable inboxes for short-lived contact routes, and check the timer before you publish one.