How to allow user to copy my email address but not crawlers?

Viewed 94

I have an issue that some crawlers that crawl the email address from my website and send spam emails.

Is there a way that allows the normal user to copy the email but not crawlers(That can't detect xxx@xxx.com format in the html source code)?

I tried the following solution, but none of them works while copying the email address:

Solution 1

Try copying this will not copy @ and .com

.name::after {
  content: '@';
}

.mail::after {
  content: '.com';
}
<span class="name">foo</span><span class="mail">gmail</span>

Solution 2

Try copying this makes foo and @gmail.com reversed.

.mail {
  display: inline-flex;
  flex-direction: row-reverse;
}
<div class="mail">
  <span>@gmail.com</span>
  <span>foo</span>
</div>

2 Answers

You can try adding an HTML comment between the email.

<div class="mail">
  <span>foo<!--not an email-->@gmail.com</span>
</div>

However, as the OP mentioned, crawlers can easily filter HMTL comments. If you run your raw code through minifyers too, comments can be filtered out.

You can also try injecting your email into DOM with Javascript.

<div id="mail"></div>
<script>
  document.querySelector("#mail").innerText = ["foo", "gmail.com"].join("@")
</script>

This makes it impossible for crawlers that don't run Javascript to see your email. To make it more usable for your users though, you can also implement copy-on-click.

<input type="text" readonly id="mail">
<script>
  let email = ["foo", "gmail.com"].join("@")
  let element = document.querySelector("#mail")
  element.value = email
  element.addEventListener('click', e => {
    element.select()
    element.setSelectionRange(0, 99999)
    document.execCommand("copy")
  })
</script>
<style>
   #mail{
     appearance: none; 
     border: 0; 
     outline: 0;
     font-family: inherit;
     font-size: inherit;
   }
</style>

The input can be styled to act like normal inline-block text. You can add a momentary tooltip that appears once copied.

You can force the user to click a button to have JavaScript copy the email for them.

document.querySelector('button').onclick = () => {

  const span = document.querySelector('span');
  const before = window.getComputedStyle(span, ':before').getPropertyValue('content').replace(/"/g, '');
  const after = window.getComputedStyle(span, ':after').getPropertyValue('content').replace(/"/g, '');

  const input = document.createElement('input');
  document.body.append(input);
  input.value = before + after;
  input.select();
  input.setSelectionRange(0, 99999);
  document.execCommand('copy');
  input.remove();
}
span:before {
  content: 'foo';
}

span:after {
  content: '@bar.com';
}
<span></span><button>Copy!</button>

Related