You are here: Home / Dog Blog / Archives

Avoiding Email-Link Spam

Tuesday 31 August, 2004 (12:40PM GMT)

The problem with putting email address links (<a href=""></a>) on web pages is that they'll be added to spam lists. In the same way that a search engine will trawl through pages to find links, "spambots" will slither their way through the net to collect email addresses for evildoing.

I have a few addresses I've used for years that get a LOT of spam, and that's due mainly to those addresses appearing on web pages. It's the reason that a lot of web sites (including HTML Dog) avoid using them. It's a shame. Sometimes you really want to include an email link on a web page. Sometimes a contact form isn't good enough on its own - you want to open up as many contact options as possible.

When using email links, there are two main ways of cutting down on potential spam. The first is to use special characters in place of normal characters, but it's not as effective as the second method - using JavaScript.

The examples I found on the net aren't great. What we really want to do in this day and age is cut out event attributes and inline JavaScript code and take full advantage of the DOM - pulling the code out of the page altogether.

So on a recent project I used this code and threw it into a separate JavaScript file:

function view_address() {
	real_address=address_to_replace.nodeValue.replace("[at]", "@");
	address_to_replace.parentNode.setAttribute("href", "mailto:"+real_address); 
window.onload = function() { view_address(); }

And then in every HTML page there is an a element that looks something like:

<a id="e">pooba[at]</a>

On the unusual occasion that JavaScript is not enabled, the user will be confronted with an understandable (not perfect, but better than nothing) email address. When JavaScript is enabled, the HTML is replaced with code that effectively resembles <a id="e" href=""></a>. It's just a normal email link as far as a human visitor is concerned. Most spambots, on the other hand, won't recognise them and won't add them to their lists.

This single-email-link-per-page (in a "contact us" section) serves my purposes, but there are obviously lots of variations on this DOM theme. If anyone has ideas for more generic code, please comment away.


Comment 1

I've always found Automatic Labs Enkoder to be useful:

So said Aaron on Tuesday 31 August, 2004 at 1:56PM GMT.

Comment 2

I don't bother. Never did. Not going to. All those email-kripling techniques give an impression that we ar giving up.
Just get decent spam filter and wait till technology improves.

So said Rimantas on Tuesday 31 August, 2004 at 2:05PM GMT.

Comment 3

That Enkoder thing produces ludicrous amounts of javascript and has no fallback for users with JS off. I wouldn't recommend using that. Although it looks pretty secure, I think that's cutting off your nose to spite your face a bit.

A little tip though, when you create new vars use the var keyword otherwise they are global rather than local to the function and could mess around with other scripts you have running. Unlikely in this case but worth doing as a matter of good practice. So, for instance:


would become:

var address_to_replace=document.getElementById("e").firstChild;

So said Dan Webb on Tuesday 31 August, 2004 at 3:01PM GMT.

Comment 4

I have used a similar technique for years, but this one is superior in that it works decently without javascript. Way to go.

So said Ed Gordon on Tuesday 31 August, 2004 at 3:03PM GMT.

Comment 5

Good idea, but this method is accessible and full standards compliance?

So said qweos on Tuesday 31 August, 2004 at 4:04PM GMT.

Comment 6

Thanks for this excellent snippet of code... now it's in my toolbox.

So said Kevin Navia on Tuesday 31 August, 2004 at 5:16PM GMT.

Comment 7

hmm, how long before email spiders catch on to the old [at] trick? any half decent coder could write a script that that found email addresses in pages using this kind of technique. However I guess it's a balance between losing accessibility and getting your arse spammed back to the stone age.

It's a nice litte script tho.

So said Jon B on Tuesday 31 August, 2004 at 6:05PM GMT.

Comment 8

Hexadecimal encoded e-mail addresses work, at least for me.

So said Anne on Tuesday 31 August, 2004 at 6:52PM GMT.

Comment 9

if they catch on to the [at] trick then the [a t] trick becomes used, or [ at ] or [ a t ]

So said Steve C. on Tuesday 31 August, 2004 at 7:24PM GMT.

Comment 10

Would be nice to have a version that looked for a class instead of an id, it seems to me that you might want to put more than one mailto: on a page from time to time. Good stuff, though.

So said Chris Hunt on Wednesday 1 September, 2004 at 9:50AM GMT.

Comment 11

Hi guys, I am new here,
I read that article and I must say that is pretty cool solution of hiding e-mail address.

I use a trick like this, instead @ I put @ and insted of dot(.) I put . in e-mail addresses.

Can anyone tell me, if it is a good solution with some reasonable explanations.

So said voloda on Wednesday 1 September, 2004 at 10:09AM GMT.

Comment 12

Sorry for my mistake, I meant ...
@ - &_#64;
dot (.) - &_#46;

"_" is nothing, read without it :)

So said on Wednesday 1 September, 2004 at 10:16AM GMT.

Comment 13

I can't remember where I saw this, but why not try using <bdo>s and typing in the e-mail address backwards?

So said Wereon on Wednesday 1 September, 2004 at 11:53AM GMT.

Comment 14

I use a system.. naa I just direct anyone who wants to send me an email to a email page on my website, no risk of spam, and it's only a mild inconvience for the modern we love forms generation :)

So said S Hayter on Wednesday 1 September, 2004 at 1:45PM GMT.

Comment 15

Personally, I like to know where I can purchase cheap viagra.

But, even if I didn't I have to say I'm not a fan of these JS based techniques. You're more or less guaranteed to get a shed load of spam whether you hide your email address or not. 'Spambots' only accelerate the inevitable and they'll soon be able to bypass all these hacks anyway. It's arguable that you're harming the accessibilty of the page by using techniques like this.

I can't think of a better way though. Except of course using a form for all email contact which would be a bit long winded in some situations.

So said Rob C on Wednesday 1 September, 2004 at 3:27PM GMT.

Comment 16

You can also use a php to hide your email address from spam bots. You provide a link to a php page that looks like this <a href = "emailHider.php?user=info&"> text</a>. It contains the following code:

So said Adam Holloway on Thursday 2 September, 2004 at 12:50AM GMT.

Comment 17

header("Location: mailto:$_GET[u]@$_GET[d]"); ?>

sorry about that.

So said Adam Holloway on Thursday 2 September, 2004 at 12:52AM GMT.

Comment 18

Nice though your suggestion is, Adam, I don't think it'd work in practice. As these spambots are spiders, they would follow the obfuscated link, thinking it to be a normal page, and receive the Location header to the real e-mail address. A well-designed spambot would then recognize that in the normal manner. Any attempts are ultimately futile, anyway. I've received spam to webmaster@(mydomain) before, without even using that address.

So said Wereon on Thursday 2 September, 2004 at 12:49PM GMT.

Comment 19

The only reliable way I have found to defeat spambots is to display email addresses as image files without mailto: links. A well-compressed png address is only about 1K.

Yes, it stinks that users can't click-and-mail, but there's something to be said for weeding out the lazy on non-commercial sites.

So said µø˜˚´¥ on Thursday 2 September, 2004 at 6:21PM GMT.

Comment 20

I work with this method:

This code insert into a head tag:
<script language="JavaScript">
function PleaseSpamNotSend(ml) { return 'to:'+ ml + '@'; }
function PleaseSendSpamToHell(ml) { return ml + '@'; }

And this code insert into page, where i want to insert a email addres:
<script language=JavaScript>
var r = ".com";
document.write('<a title="Any qustions? Send mail!" href="m' + 'ail'+ PleaseSpamNotSend('www') + "yourdomain" + r + '">' + PleaseSendSpamToHell('www') + '</a>');

Im no recive any spam for 2 years ago.

So said Alexey on Friday 3 September, 2004 at 3:19AM GMT.

Comment 21

Sorry. Gave up on email addresses. Web forms for me. But if I was to put the email address up, I'd probably do what Simon Wilson did - put it behing a form button. On submit, show the address. Slightly inconviences the user but hey...

So said Andrew Bowden on Friday 3 September, 2004 at 12:39PM GMT.

Comment 22

The reason why you were receiving the email at your webmaster@(mydomain) address is that most spam bots send emails to that is a common address for most domains. This makes it likely target for spam.

There are a lot of trade offs when fighting spam mainly dealing with the convenience to the user versus reducing the amount of spam you receive is a tough task. I'm not a fan of using web forms for email. Sure it prevents spam, but as a user, I prefer to use my own email client. When I post email addresses, I use a javascript technique (similar to the one posted here). This combined with a good filter keeps the spam in my inbox to a minimum.

So said Adam Holloway on Friday 3 September, 2004 at 5:22PM GMT.

Comment 23

I am completely ignorant of how to put those javascripts into my site... Someone please assist! :( I have a good understanding of a lot of this, but I just don't know where to put the script so that the id="#" attribute references the right script. Help!

So said bret on Sunday 5 September, 2004 at 4:13AM GMT.

Comment 24

I use Dreamweaver with an extension called Linecraft Hide Email, Has worked well for me.

So said Anne Hecht on Thursday 9 September, 2004 at 8:48PM GMT.

Comment 25

Here is a css technique that uses the :after selector and the content property.

Can this be separated? for example:
address:after{content: " <cheeaun"}
address:after{content: "\40"}
address:after{content: ""}

So said Will Rickards on Friday 10 September, 2004 at 8:46PM GMT.

Comment 26

This doesn't stop dictionary attacks, name attacks etc and replacing the @ with it's unicode (or other) equivalent is encoding, not encryption. Just because (substitute your address) isn't found on the web doesn't mean it won't get spammed. Write the email in human form rather than the mailto: link, even: e.g my mailbox is john, my domain is -- but that still won't stop the spam :D.
The way to reduce spam is to implement effective filters at the server level, make it unprofitable for bulk emailers, enforce the laws and ship email clients with HTML turned off by default, or turn off object and iframe support in them for good if you really want red text (goes a good way to stop those Win32 boxes from becoming from becoming owned relays).

So said James on Sunday 12 September, 2004 at 2:06PM GMT.

Comment 27

Hey --

Nice little script! I'm not a javascript guy, but I assume it's possible to tweak it so that a "display name" can be used. In other words, I'd like the page to read "Joe Blow", but have it linked to

If it's not too much trouble, could ya hook me up? I think lots of others would like this too...

So said Mik on Thursday 30 September, 2004 at 2:01AM GMT.

Comment 28

Minor enhancement to support multiple email addresses on the page:

if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a")
var i
for (i = 0; i < a.length; i++) {
if (a[i].className && a[i].className == "e") {
address_to_replace = a[i]

So said richard on Saturday 9 October, 2004 at 4:25PM GMT.

Comment 29

p.s. change id= to class=


So said richard on Saturday 9 October, 2004 at 4:28PM GMT.

Comment 30

anybody knows if spam robots scan external CSS ?

So said Timmy on Tuesday 16 November, 2004 at 1:26PM GMT.

Comment 31

No they don't

So said Steve on Saturday 20 November, 2004 at 2:04PM GMT.

Comment 32

I can't get richard's enhancement to work. I have tried using the original code where he has put "...", but it only gives me this JavaScript error in debug:
Error: address_to_replace.nodeValue has no properties

So said el mono on Thursday 24 February, 2005 at 3:21PM GMT.

Comment 33

I just found out what was wrong, address_to_replace was missing .firstChild. I've also modified the enhancement so that you can now use other classes on the links if needed. The enhanced code is as follows:

function view_address() {
if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a")
var i
for (i = 0; i = 0) {
address_to_replace = a[i].firstChild;
real_address = address_to_replace.nodeValue.replace("[at]", "@");
address_to_replace.nodeValue = real_address;
address_to_replace.parentNode.setAttribute("href", "mailto:" + real_address);
window.onload = function() { view_address(); }

Save the above as a .js file, include it in your HTML header, and use it like this:

So said el mono on Thursday 24 February, 2005 at 3:30PM GMT.

Comment 34

For more strong security I have used php code to change string that replaced for every user agent. So it's not a static string that spam-robots can collect and pass by.
I have created a file
email_protection.js.php which contain one function (not original):

function view_address() {
if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a");
var i;

$mark='{for '.getenv('HTTP_USER_AGENT').'}'.'[at server]';
echo "var mark = '".$mark."';\n";

for (i = 0; i pooba<?php echo
'{for '.getenv('HTTP_USER_AGENT').'}'.'[at server]';

So we have different strings!!! Spam-robots mast collect this.
You can use date or md5 for each page...

So said Vlad on Wednesday 17 August, 2005 at 12:50PM GMT.

Comment 35


email_protection.js.php (function was changed):

function view_address() {
if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a");
var i;
$mark='{for '.getenv('HTTP_USER_AGENT').'}'.'[at server]';
echo "var mark = '".$mark."';\n";
for (i = 0; i pooba<?php
echo '{for '.getenv('HTTP_USER_AGENT').'}'.'[at server]';

So said Vlad on Wednesday 17 August, 2005 at 12:54PM GMT.

Comment 36

Sorry again! Last try.


function view_address() {
if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a");
var i;
$mark='{for '.getenv('HTTP_USER_AGENT').'}'.'[at server]';
echo "var mark = '".$mark."';\n";
for (i = 0; i < a.length; i++) {
if (a[i].className && a[i].className == "e") {
var address_to_replace = a[i].firstChild;
var real_address = address_to_replace.nodeValue.replace(mark, "@");
address_to_replace.nodeValue = real_address;
address_to_replace.parentNode.setAttribute("href", "mailto:" + real_address);


So said Vlad on Wednesday 17 August, 2005 at 12:56PM GMT.

Comment 37

Last-last try!


<a class="e">pooba<?php echo
'{for '.getenv('HTTP_USER_AGENT').'}'.'[at server]';

So said Vlad on Wednesday 17 August, 2005 at 12:58PM GMT.

Comment 38

Hey, that's really great. Thanks a lot. I've used that little code (with some minor tuning) to my own webpage. Thanks for sharing it.

So said bob on Monday 9 January, 2006 at 1:08AM GMT.

See Also

^ Top

SiteGround: Fast, reliable, recommended hosting.