DEV Community

Christopher Wray
Christopher Wray

Posted on • Edited on

5 2

Building a Honeypot Field in Nuxt

I will end up using Netlify Forms for my website because my backend is hosted on Heroku, and each time a user submits a form, the server has to rebuild, which makes a form submission really slow if it is the first form submitted since the Heroku server shut down.

That being said, just for fun, I built a honeypot field in my ContactForm Component.

To do this, I checked if the field has a value when the user goes to submit the form and destroyed the form if it does. Otherwise, proceed with the form submission process.

Here is the script tag:

export default {
  data() {
    return {
      loading: false,
      success: false,
      errored: false,
      isBot: false,
      name: "",
      bot: null,
      email: "",
      phone: "",
      message: "",
    };
  },
  methods: {
    sendMessage() {
      this.loading = true;
      /* This is where I check if the bot field has a value. 
         Only bots will fill this out. */
      if(this.bot != null){
        this.isBot = true;
      }
      // Otherwise the form will try to go through.
      else {
        this.$axios
        .post("/messages", {
          name: this.name,
          email: this.email,
          phone: this.phone,
          message: this.message,
        })
        .then((response) => {
          this.success = true;
          this.errored = false;
        })
        .catch((error) => {
          this.errored = true;
        })
        .finally(() => {
          this.loading = false;
        });
      }

    },
  },
};
Enter fullscreen mode Exit fullscreen mode

Here is the Template:

<template>
  <div>
    <!-- First, we make sure we don't have a bot -->
    <div v-if="isBot" class="rounded bg-orange-500 text-white text-lg p-4">
      Great! You have proven to be a bot! I've destroyed the form from the page, and acted like you successfully sent the form.
    </div>
    <!-- Then we show the rest of the component if not. -->
    <div v-else>
    <div v-if="success" class="rounded bg-indigo-500 text-white text-lg p-4">
      Great! Your message has been sent successfully. I will try to respond
      quickly.
    </div>
    <form
      v-else
      v-on:submit.prevent="sendMessage"
      class="grid grid-cols-1 gap-y-6"
    >
      <div v-if="errored" class="rounded bg-red-200 text-lg p-4">
        Bummer, Something went wrong. Did you fill out all of the fields?
      </div>
      <div>
        <label for="full_name" class="sr-only">Full name*</label>
        <div class="relative rounded-md shadow-sm">
          <input
            v-model="name"
            required
            name="name"
            id="full_name"
            class="form-input block w-full py-3 px-4 placeholder-gray-500 transition ease-in-out duration-150"
            placeholder="Full name*"
          />

        </div>
      </div>
      <!-- The whole field and label is set to display hidden with Tailwind CSS -->
      <div class="hidden">
            <label class="sr-only"
              >Don’t fill this out if you're human: </label>
              <input v-model="bot" name="bot-field" placeholder="This field is only for the robots." class="form-input block w-full py-3 px-4 placeholder-gray-500 transition ease-in-out duration-150"
            />
      </div>
      <div>
        <label for="email" class="sr-only">Email*</label>
        <div class="relative rounded-md shadow-sm">
          <input
            required
            v-model="email"
            name="email"
            id="email"
            type="email"
            class="form-input block w-full py-3 px-4 placeholder-gray-500 transition ease-in-out duration-150"
            placeholder="Email*"
          />
        </div>
      </div>
      <div>
        <label for="phone" class="sr-only">Phone</label>
        <div class="relative rounded-md shadow-sm">
          <input
            v-model="phone"
            name="phone"
            id="phone"
            class="form-input block w-full py-3 px-4 placeholder-gray-500 transition ease-in-out duration-150"
            placeholder="Phone"
          />
        </div>
      </div>
      <div>
        <label for="message" class="sr-only">Message</label>
        <div class="relative rounded-md shadow-sm">
          <textarea
            required
            v-model="message"
            name="message"
            id="message"
            rows="4"
            class="form-input block w-full py-3 px-4 placeholder-gray-500 transition ease-in-out duration-150"
            placeholder="Message*"
          ></textarea>
        </div>
      </div>
      <div class="">
        <span class="inline-flex rounded-md shadow-sm">
          <button
            type="submit"
            class="inline-flex justify-center py-3 px-6 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out"
          >
            {{ loading ? "Sending Message..." : "Submit" }}
          </button>
        </span>
      </div>
    </form>
    </div>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

And here is what the nice little notification looks like when a bot decides to fill out my form:

The Bot field notification

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up