Link Obfuscation for Email and Phone Numbers in Astrojs

Spiders and automated programs often scan websites for email addresses and phone numbers to harvest for spam campaigns. Obfuscation scrambles the data, making it unreadable to these bots and significantly reducing the chances of receiving unwanted emails or calls.

While obfuscation protects your information to some extend, it doesn’t prevent users from contacting you. The idea behind the implementation proposed in this article is to Base64-encode the sensitive data and reverse the characters. The result is assigned to a data attribute while the standard href attribute contains no sensitve data. A small Javascript script will load automatically and will decode the value of the data attribute once the element get into the viewport.

Reusable Component

This is the code for the reusable component located in src/components/ObfuscatedLink.astro:

 1---
 2type Props = {
 3  href: string;
 4};
 5
 6const { href } = Astro.props;
 7
 8function reverseStr(str: string) {
 9  return str.split('').reverse().join('');
10}
11
12const id = ''+process.hrtime()[1];
13
14const obfuscatedHref = reverseStr(Buffer.from(href).toString('base64'));
15
16const text = await Astro.slots.render('default');
17const obfuscatedText = reverseStr(Buffer.from(text).toString('base64'));
18---
19
20<a href="#" id={id} data-href={obfuscatedHref} data-text={obfuscatedText}>[hidden]</a>
21
22<script is:inline define:vars={{ id, obfuscatedHref, obfuscatedText }}>
23function reverseStr(str) {
24  return str.split('').reverse().join('');
25}
26new IntersectionObserver((entries, observer) => {
27  if (entries[0].isIntersecting) {
28    const el = entries[0].target;
29    el.href = window.atob(reverseStr(el.attributes['data-href'].value));
30    el.innerHTML = window.atob(reverseStr(el.attributes['data-text'].value));
31    observer.disconnect();
32  }
33}).observe(document.getElementById(id));
34</script>

Example Usage

The component can be used just like a standard link tag:

1---
2import ObfuscatedLink from '../components/ObfuscatedLink.astro';
3---
4
5<p>
6  Contact me via:
7  <ObfuscatedLink href="mailto:mail@example.com">mail@example.com</ObfuscatedLink>
8</p>

Astro will generate the following HTML code:

1<p>
2  Contact me via:
3  <a href="#" id="239889741" data-href="=02bj5SZsBXbhhXZAxWah1mOvRHbpFWb" data-text="==QbvNmLlxGctFGelBEbpFWb">[hidden]</a>
4  <script>[...]</script>
5</p>

With Javascript disabled, the link will have no action and display only the text “[hidden]”. The sensitive data remains encoded in the data attributes.

This obfusction does not aim to properly protect senstive data, but to make is harder for scrapers to automatically extract valid email addresses or telephone numbers. The impact to regular users should be minimal.