In this step-by-step guide, we will show you how you can protect your website contact form from spam submissions.

You will be able to implement this solution without a heavy back-end or any captcha methods, only HTML and some JavaScript are needed.

Classic HTML form

Below you can see a default example of the HTML form:

<form action="/send-contact-form" method="POST">
  <input type="text" name="name" id="name">
  <input type="email" name="email" id="email">
  <textarea name="question" id="question"></textarea>
  <input type="submit" value="Send!">
</form>

Spammers don’t fill these types of forms manually. They use automated robot scripts to submit thousands of forms across the internet.

So how do those spam scripts work?

They read your website HTML code and search for the content that is placed between <form></form> tags.

Then the script takes all the <input> field names and fills with the spammy data. After all this data is submitted to the specific endpoint from the action=”” parameter.

Because HTML form is very standardized it is easy to create automated robots to submit these types of forms.

Below we’ll show you two ways on how you can protect your HTML form.

Hidden “honeypot” field to protect you form

This one is the most commonly used method across the internet. It will reduce the number of spam submissions, but will not fully protect your form.

Let’s take a look at the form below:

<form action="/send-contact-form" method="POST">
  <input type="text" name="name" id="name">
  <input type="email" name="email" id="email">
  <textarea name="question" id="question"></textarea>

  <div style="display: none; visibility: hidden;">
    <input type="text" autocomplete="off" name="standard-type" id="standard-type">
  </div>

  <input type="submit" value="Send!">
</form>

We have added an extra field with name “standard-type” (field name can be any value) and it is inside the DIV with additional style that will hide the field from your site visitors.

If we know that robots read and fill all the inputs between <form></form> tags, they probably will fill this hidden input as well. And if this field is hidden from real people, they will never be able to add any value to it.

That’s how it works.

All we need to do is to add a validation to our back-end – send email only if this field is empty.

With this method, avoid using the field name “honeypot”, because most bots detect this name. Also don’t use regular naming, like company, role, city, etc. because some browser extensions may autofill inputs with these names.

The amount of spam will be reduced heavily. Still some robots are smart enough to detect hidden fields and leave them blank. That’s why you may want to go with the below solution.

Use JavaScript to submit your form

This method requires more work than simply adding a hidden field. But it will almost completely prevent spam submissions.

Also, while using this method, you will reduce the load on your back-end, because the majority of bots will not submit the form at all.

How does it work?

We know that bots are reading content between the <form></form> tags. Why don’t we remove those tags, so our code will look like:

<div>
  <input type="text" name="name" id="name">
  <input type="email" name="email" id="email">
  <textarea name="question" id="question"></textarea>

  <div style="display: none; visibility: hidden;">
    <input type="text" autocomplete="off" name="standard-type" id="standard-type">
  </div>

  <input type="submit" value="Send!">
</div>

From the site visitor’s perspective, nothing changed, they still see the same input fields.

But when clicking the submit button nothing is going to happen…

To fix that, let’s do some changes.

First, change the submit button type to “button” and add an “onclick” event:

<input type="button" value="Send!" onclick="sendData()">

Second, add the following JavaScript code:

<script>
  const requestUrl = '/send-contact-form'

  function sendData() {
    let formBody = [
      'name=' + encodeURIComponent(document.getElementById('name').value),
      'email=' + encodeURIComponent(document.getElementById('email').value),
      'question=' + encodeURIComponent(document.getElementById('question').value),
      'standard-type=' + encodeURIComponent(document.getElementById('standard-type').value)
    ].join('&')

    let xhr = new XMLHttpRequest()

    xhr.open('POST', requestUrl)

    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8')

    xhr.onload = function () {
      if (xhr.status === 200) {
        // Redirect to your thank you page
        window.location = '/thank-you-page'

        return
      }

      alert('An error occurred')
    }

    xhr.send(formBody)
  }
</script>

It is the same data submission, but with random JavaScript code instead of using HTML form action.

It is a good practice to validate the input data using JavaScript alongside your back-end script. So you will have multiple layers of validation.

For example, we can validate name input in JavaScript by adding the following code before the xhr.send() method:

let name = document.getElementById('name').value

if (name.length === 0 || typeof name.length === 'undefined') {
  alert('Please enter your name')
  return
}

You can find an extended example in this codepen.

Conclusion

You can start by applying only the first solution – add the honeypot field to your form and this will reduce the number of unwanted form submissions. If you see that this is still not protecting your form as well as you want, you can apply the JavaScript trick then.

With JavaScript, you can create a nice form submission process without page reload. The link provided above shows a success or error message in the same window.

If you’ll apply JavaScript validation, you will also reduce the number of invalid attempts to your server from real people. This will also reduce the load on your back-end.

Hope you’ve liked this tutorial. If you have any questions, write a comment below.

We also have prepared a step-by-step guide on how to send email from a website contact form using Google Cloud Functions with PHP, SMTP2GO and Templid