Strategies to prevent email harvesting and a specific templating issue

I have my email exposed on my website. Since I did this, the spam has become overwhelming.

I now want to delete this email address and lightly obscure my email address such that it is a bit more difficult for bots to harvest the address and use it for spam.

I have considered various techniques:

1: Use mail at example dot com instead of mail@example.com. This will work well with tech savvy users at their desktop with a keyboard and mouse. However, for non-tech savvy users, they might become confused. And mobile users will just not bother writing the email out and move on. Tech savvy or not.

2: Use CSS :before and :after, etc. to display the email address. This is not desirable because it makes it impossible to select the email address, and also the user cannot click the address in a mailto: link.

3: Use javascript to document.write the email address or the mailto: link. This works transparently on all users that have js enabled. If the script is inline, it will even work with people who disallow external or third party scripts.

For now, I think number 3 is the best approach.

I would love to hear your approach to this.

Note: I am not after a bullet proof solution.
I guess a near bullet proof solution is to just use a web-form and a captcha like hcaptcha.
However, I personally hate webforms and prefer using an email if such is provided, and even though I have a webform and some users use it, I have gotten really valuable contacts from people actually using the email.

Now, when I try to implement strategy number 3, I face a problem with jekyll:

I do not want to have to type out a javascript one-liner every time I have to refer to my email address. So to make it easier, I have made an _includes file called “obscured-email.html”. It contains:

<script type="text/javascript">document.write('{{ site.data.vars.contact_email }}');</script>

And a file called obscured-email-link.html containing:

<script type="text/javascript">document.write('<a href="mailto:{{ site.data.vars.contact_email }}">{{ site.data.vars.contact_email }}</a>');</script>

When I need to refer to my email address or include an email link, I can just do this:

"{%- include obscured-email.html -%}"                        
"{%- include obscured-email-link.html -%}"

Problem is, however, that when I do the above, it will write: "info@example.com "
where I would expect it to write:
"info@example.com"

Notice the added space before the doublequote?

How do I get rid of this?

I thought {%- ... -%} should strip the whitespace?
It seems to do this only on the left side?

I suspect this has to do with the text file probably ending in a newline. And I have tried getting rid og the final newline, but my editor seems to insist on keeping it there…

How to solve?

Is there a better approach for this than my include trick?

Is there really not any solution to the issue I am experiencing with the include file?

Having tried all kinds of things with |strip |trim, etc., I settled on removing the last byte from the file like this:

truncate -s -1 _includes/obscured-email.html

This is annoying because this means everytime I edit this file, I have to re-run this command. But oh, well. It works.

I thought {%- ... -%} should strip the whitespace?

It strips the whitespace before and after, not inside. Maybe you site.data.vars.contact_email is already coming with a trailing space? The best way to check this would be to add a console.log("{{ site.data.vars.contact_email }}"); inside your script to print it out.

It seems to be that the problem is that the file that I include contains a newline at the end. This newline is, of course, whitespace which results in the space added. The problem is that I cannot avoid this newline at the end of file as most editors seem to add this (tried vim, nano, sublime text, etc). I can remove it using the truncate command as above, and then it works! But, alas, having to remove this every time I edit the file is quite annoying and error prone… Was hoping there be some way to have Jekyll actually strip it. But I guess it does not work like that when including the file…

It doesn’t make sense because this is the part that edits the html

<script type="text/javascript">document.write('{{ site.data.vars.contact_email }}');</script>

So when you include the file, the additional space would be after the </script> tag, not inside the write command.

It does make sense but it is counter-intuitive.

Try this:

Put these lines in some html file:

"{%- include obscured-email.html -%}"
"{%- include obscured-email-link.html -%}"

Then create the two include files:

$ cat _includes/obscured-email.html   
<script type="text/javascript">document.write('{{ site.data.vars.contact_email }}');</script>

$ cat _includes/obscured-email-link.html     
<script type="text/javascript">document.write('<a href="mailto:{{ site.data.vars.contact_email }}">{{ site.data.vars.contact_email }}</a>');</script>

Then see how Jekyll renders the html file.

It will produce this:

"info@example.com " "info@example.com "

Note the space before the "

Now, try to truncate the include files:

$ truncate -s -1 _includes/obscured-email.html
$ truncate -s -1 _includes/obscured-email-link.html

Now, let’s see how Jekyll renders the html file:

"info@example.com" "info@example.com"

I have tested this again just now in a minimal setup.

It seems the - does not have any effect when including files. That is, they do not strip the content of the file (thus, they do not remove the trailing newline char)

Not sure if this is a bug or not. It is pretty confusing…

Like I said, the - removes spaces before or after the tag (in this case include), not of its contents. Let me show you how it works here. Using the same content of your files, including the extra new line, just changed site.data.vars.contact_email to site.email2 here.

<script type="text/javascript">document.write('{{ site.email2 }}');</script>

<script type="text/javascript">document.write('<a href="mailto:{{ site.email2 }}">{{ site.email2 }}</a>');</script>

In my layout it looks like this (note the indentation spaces to the left):

    <!-- Footer -->
    {% include footer.liquid %}
    {% include obscured-email.html %}
    {% include obscured-email-link.html %}

    <!-- JavaScripts -->
    {% include scripts.liquid %}

And the output looks like this:

  </footer>


    <script type="text/javascript">document.write('some@email.com');</script>

    <script type="text/javascript">document.write('<a href="mailto:some@email.com">some@email.com</a>');</script>


    <!-- JavaScripts -->
    <!-- jQuery -->

Now, if we do it with the {%- -%}:

    <!-- Footer -->
    {% include footer.liquid %}
    {%- include obscured-email.html -%}
    {%- include obscured-email-link.html -%}

    <!-- JavaScripts -->
    {% include scripts.liquid %}

it outputs

  </footer>

<script type="text/javascript">document.write('some@email.com');</script>
<script type="text/javascript">document.write('<a href="mailto:some@email.com">some@email.com</a>');</script>
<!-- JavaScripts -->

In this case it removes the indentation spaces and the empty newlines between the tags. That’s how it works. Also note that the emails were put there correctly, without extra spaces.

That’s why I said that maybe your site.data.vars.contact_email is already coming with a trailing space.