Netlify not getting forms after implementing recaptcha in my Nuxt application

My netlify site name: https://rubiko-company-site.netlify.app/

I’m using nuxt and veevalidate to validate a form and I just added recaptcha to my form. It has come to my attention than due to hidration problems between Nuxt and the way Netlify implement forms the way to go is to implement a custom-recaptcha-2. So I did that using the @nuxtjs/recaptcha module, getting a site key and a secret key, creating an .env file inside my nuxt implementation and setting up the env variables on netlify.

The problem is that as much as I tried and read documentation apparently the captcha never sent the form back to the server, I can see my own success message, I can see the payload ok in the browser but I never see the Submissions from my form in Netlify.

Here’s the way I have implemented my form:

<template>
  <div class="contact">
    <ValidationObserver
      ref="observer"
      tag="form"
      class="contact-form"
      name="contact"
      method="post"
      data-netlify="true"
      data-netlify-honeypot="bot-field"
      data-netlify-recaptcha="true"
      @submit.prevent="send()"
    >
      <p v-if="message" class="contact-message">
        {{ message }}
      </p>
      <input type="hidden" name="form-name" value="contact" />
      <ValidationProvider
        v-slot="{ errors }"
        vid="name"
        name="Name"
        rules="required"
      >
        <input
          v-model="mail.Name"
          type="text"
          name="Name"
          value=""
          size="40"
          :class="{ 'border-error': errors[0] }"
          class="validate"
          aria-required="true"
          aria-invalid="false"
          placeholder="Name"
        />
        <span class="label-error">{{ errors[0] }}</span>
      </ValidationProvider>
      <ValidationProvider
        v-slot="{ errors }"
        vid="email"
        name="Email"
        rules="required|email"
      >
        <input
          v-model="mail.Email"
          type="email"
          name="Email"
          value=""
          size="40"
          :class="{ 'border-error': errors[0] }"
          class="validate"
          aria-required="true"
          aria-invalid="false"
          placeholder="Email"
        />
        <span class="label-error">{{ errors[0] }}</span>
      </ValidationProvider>
      <input
        v-model="mail.PhoneNumber"
        type="text"
        name="PhoneNumber"
        value=""
        size="40"
        class="validate not-required"
        aria-required="true"
        aria-invalid="false"
        placeholder="Phone Number"
      />
      <input
        v-model="mail.Company"
        type="text"
        name="Company"
        value=""
        size="40"
        class="validate not-required"
        aria-required="true"
        aria-invalid="false"
        placeholder="Company"
      />
      <ValidationProvider
        v-slot="{ errors }"
        vid="message"
        name="Message"
        rules="required"
      >
        <textarea
          v-model="mail.Message"
          name="Message"
          cols="40"
          rows="4"
          :class="{ 'border-error': errors[0] }"
          class="validate"
          aria-required="true"
          aria-invalid="false"
          placeholder="Your Message"
        ></textarea>
        <span class="label-error">{{ errors[0] }}</span>
      </ValidationProvider>
      <div class="captcha" data-netlify-recaptcha="true">
        <recaptcha />
      </div>
      <p class="send-btn">
        <button class="btn btn--primary" type="submit">
          Get In Touch!
        </button>
      </p>
    </ValidationObserver>
</template>
<script>
import {
  ValidationObserver,
  ValidationProvider,
  extend,
} from 'vee-validate/dist/vee-validate'
import { required, email } from 'vee-validate/dist/rules.umd'

extend('required', {
  ...required,
  message: 'Please enter your {_field_}',
})
extend('email', {
  ...email,
  message: 'Your Email must be a valid email address',
})

export default {
  components: {
    ValidationObserver,
    ValidationProvider,
  },
  data() {
    return {
      mail: {
        Name: '',
        Email: '',
        PhoneNumber: '',
        JobTitle: '',
        Company: '',
        Message: '',
      },
      sending: false,
      message: null,
    }
  },
  methods: {    
    async send() {
      const isValid = await this.$refs.observer.validate()
      await this.$recaptcha.getResponse()
      if (isValid) {
        this.sending = true
        this.message = null
        fetch('/', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: this.encode({ 'form-name': 'contact', ...this.mail }),
        })
          .then(() => {
            this.sending = false
            this.mail.Name = ''
            this.mail.Email = ''
            this.mail.PhoneNumber = ''
            this.mail.Company = ''
            this.mail.Message = ''
            this.$refs.observer.reset()
            this.message =
              'Thanks for writing! The message has been sent successfully. We will be in touch soon.'
            this.$recaptcha.reset()
          })
          .catch((error) => {
            this.sending = false
            this.message =
              'Sorry for the inconvenience, but there was an error sending the message. Please contact info@rubiko.tech pasting the following error message:' +
              error
          })
      }
      await this.$recaptcha.reset()
    },
  },
}
</script>

I really hope you can help me because it’s been really hard to find info due to my specific scenario.

Hey there, @Lowtrux :wave:

Thanks for reaching out! Can you please share your form name as it exists in the UI? Additionally, can you confirm you have read our forms Support Guide?

1 Like

Hello hillary, thanks for your reply.

The form name in the UI is “contact”. I have read your support guide and also follow the proper steps to implement a custom captcha (in my case google). The form was working pretty fine before I implemented the captcha but now I can’t see any of the form replies on the Netlify dashboard. And when I remove the captcha it starts to work fine so I’m guessing there’s an implementation problem there, I just can’t understand what’s the problem.

Many thanks.

Hey @Lowtrux,

I tried the form here: Rubiko | Contact Sales, but I wasn’t presented with a ReCaptcha. Have you removed it?

Yes, since I couldn’t get our filled forms on Netlify in prod. Is there any way to reproduce the code so I don’t have to upload those changes to our prod site? Thanks!

Hi @Lowtrux,

You could create a branch and then do a branch deploy. If you worry about unintentionally deploying to production, you can lock your production deploy by following this Netlify Doc:

Our docs on Branch deploys can be found here:

You could create a branch with the code, and deploy it as a branch deploy which would give you the chance to deploy the code that you’re having issues with without it being in production.

@hrishikesh I have replicate the scenario in our test branch, now you will have the captcha in:
Rubiko | Contact Sales.

Many thanks !

Many thanks @Melvin. I remembered that we had a test branch so I merged it with the master and then push my test code to the test branch.

Could you share the function that’s handling the submission of the form?

I believe you’re not sending the Google Recaptcha output and thus, Netlify is probably ignoring the submissions.

@hrishikesh all the code is in my original post, I have already shared it.

Ahh sorry, yes.

As I mentioned, this is happening because you’re not sending the Captcha response. A successful request should look like:

It should include a field called g-recaptcha-response. Since you’re using JavaScript, you’ll have to capture the value yourself and send it along with the submission.

@hrishikesh many thanks. Any chance you can provide an example of how to do this or maybe provide a link that explain it a little more in depth. I will really appreciate it.