Best way to protect the Email address on webpage


  1. I was trying to use a php redirection technique from this page, but Grav does not allow to run php scripts no matter how permissive are the privileges.
<p> If you have any questions or suggestions, please write us an
<a href="redirect-mailto.php">email</a>.

The content of the redirect-mailto.php file is a script that redirects to the actual mailto link:

  1. Then I use the recommendation on this forum post, it works but when I see the webpage code it simply substitutes the ASCII characters of the email address for its equivalent HTML identity, and I guess that trick can be overcome by spam bots:
    Mailto spam protect

  2. Is there a better way that you can recommend to protect emails addresses from being harvested?, I do not want to use an email form, I had countless of problems from spammers abusing email forms.

3.1 I would prefer to use solution on point 1 but I do not want to touch de secirity default values of Grav, so how can I run this single php script only?

Best regards

@joejac, Did you search in Grav’s plugin repository?

Thanks for the reply @pamtbaau No, I did not know they have a plugin to obfuscate the email, I discovered now that I checked. In the future before posting I will check the plugins. The Antispam plugin as they say has an “odd bug” and I do not think obfuscating mails is 100% effective like the php option, or am I missing something here with that script?.

On the other side, that script is going to look and work into all pages and I have the link only in a single module of the modular home page. I do not want to go disabling the script on all pages. My working philosophy is: “the less intrusive scripts the better” I already have 12 plugins activated. Any other idea is also welcomed.
Thanks and regards


I do not think obfuscating mails is 100% effective like the php option, or am I missing something here with that script?

As far as I know, there is no 100% effective solution for email obfuscation. Each “solution” has its drawbacks…

Having said that… This plugin does use a more complex algorithm to obfuscate the email address. The plugin refers to an article for more information on the algorithm.

that script is going to look and work into all pages

If you have any suggestions to improve the plugin, please create an issue at Github…

@joejac, If you want to go with your solution, you could try the following:

  • Create plugin named ‘nospam’ using $ bin/plugin devtools new-plugin
  • Edit its nospam.yaml like:
    enabled: true
  • Edit function ‘onPluginsInitialized’ and add:
    /** @var Uri */
    $uri = $this->grav['uri'];
    $url = $uri->route();
    if ($url === '/nospam') {
      $query = rtrim($uri->query(), '=');
      $email = $this->config->get("$query");
      header("Location: mailto:$email");
  • And add the following to the page:
    <p> If you have any questions or suggestions, please write us an
      <a href="/nospam?info" target="_blank">email</a>.
    Note: query parameter ‘info’ must match value in nospam.yaml.

Did have a look at the age old problem as a friends site is currently getting bombarded with spam due to a bad web developer.

Nice Read
html - How to spamproof a mailto link? - Stack Overflow

The cleverest ones seemed to be the
You can use external services like which I hadnt heard of before but you create a hyperlink to the mailto command.

And this one

My version generates the link on the fly from a base64-encoded email string when the user hovers over the link, or if on a mobile device, touches it. All links with the attribute ‘data-gen-email’ will work.

// The string is your base64-encoded email
const emailAddress = atob("bWFpbHRvOnlvdUBkb21haW4uY29t");

// Select all links with the attribute 'data-gen-email'
const emailLinks = document.querySelectorAll('[data-gen-email]');

emailLinks.forEach(link => {
    link.onmouseover = link.ontouchstart = () => link.setAttribute('href', emailAddress);

You can encode your email to base64 by using btoa('') , or elsewhere on the web:

btoa(''); // "bWFpbHRvOnlvdUBkb21haW4uY29t"

Example link in html:

<a href="#" target="_blank" data-gen-email>Email Me!</a>

So no mailto appears on the page … and also grav does have a base64 encode /decode twig function , you just need an online generator to produce the code or create a blueprint or a template varable in grav or carry on with the plugin idea … Twig Filters | Grav Documentation (

Thanks to pamtbaau and his code / plugin insite … its a really good start !

1 Like

Thanks a lot @pamtbaau and @spamhater very nice and useful solutions.
Given my lack of programming skills I think @spamhater solution would be easy for me to do. I will take note of @pamtbaau nice plugin code so in the future I will be able to study it and practice my first plugin :face_with_monocle:
Best regards

@joejac, Once you you implemented a solution, would you mind feeding back to the forum which solution you have chosen and how you have implemented it?

Thanks a lot @spamhater it works nice, the email address is not shown in any form in the HTML code. I am marking your solution as the one I am using now. I am pretty sure that @pamtbaau solution also works, but for my present skill level @spamhater solution is easier. Thanks for your valuable time and your kind help to both.

  1. I went here and encoded:
  2. I used in this way:
<div class="socialbar" style="margin-top: 50px;">
                 <a href="#" target="_blank" data-gen-email alt="Contacta por Gmail" title="Contacta por Gmail" ><img class="gmailicon" src="gmailicon.png" /></a>
              <script type="text/javascript">
                // The string is your base64-encoded email
                const eAddress = atob("TheBase64Code");
                // Select all links with the attribute 'data-gen-email'
                const eLinks = document.querySelectorAll('[data-gen-email]');
                    eLinks.forEach(link => {
                        link.onmouseover = link.ontouchstart = () => link.setAttribute('href', eAddress);
  1. I placed the Code of point 2 in the following 3 files:

And it worked fine
Best regards

1 Like