Issue with Gatsby Netlify Form not receiving Submissions

594 views Asked by At

I got the Netlify form working and accepting submissions but once I started setting up AJAX according to https://docs.netlify.com/forms/setup/, I can't figure out why submissions aren't being received.

Things I've tried:

  1. Removing Hidden "form-name" input
  2. Removing Recaptcha
  3. Running "gatsby clean"
  4. Removing opening Form tag's method attribute (method: "POST")
  5. Removing action attribute from the opening Form tag and setting it directly in handleSubmit: .then(() => navigate("/thank-you/"))

Any suggestions or fixes are really appreciated!

contact-form.js:

import React, { setState } from "react"
import styled from "styled-components"
import Recaptcha from "react-google-recaptcha"
import { navigate } from "gatsby"
import { Button, Col, Form, Row } from "react-bootstrap"
import { breakpoints } from "../utils/breakpoints"

const RECAPTCHA_KEY = process.env.GATSBY_RECAPTCHA_KEY

export default function ContactForm() {
  const [state, setState] = React.useState({})
  const recaptchaRef = React.createRef() // new Ref for reCaptcha
  const [buttonDisabled, setButtonDisabled] = React.useState(true)

  const handleChange = e => {
    setState({ ...state, [e.target.name]: e.target.value })
  }
  const encode = data => {
    return Object.keys(data)
      .map(key => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
      .join("&")
  }
  const handleSubmit = e => {
    e.preventDefault()
    const form = e.target
    const recaptchaValue = recaptchaRef.current.getValue()

    fetch("/", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: encode({
        "form-name": "contact",
        "g-recaptcha-response": recaptchaValue,
        ...state,
      }),
    })
      .then(() => navigate(form.getAttribute("action")))
      .catch(error => alert(error))
  }
  return (
    <Form
      name="contact"
      method="POST"
      netlify
      action="/thank-you"
      netlify-honeypot="bot-field"
      data-netlify-recaptcha="true"
      onSubmit={handleSubmit}
    >
      <Row>
        <Col md={12}>
          <h3>Message Us</h3>
        </Col>
      </Row>
      <Row>
        <Col md={6}>
          <Form.Group hidden>
            <Form.Label htmlFor="bot-field">
              Bot Field: Humans do not fill out!
            </Form.Label>
            <Form.Control name="bot-field" />
            <Form.Control name="form-name" value="contact" />
          </Form.Group>
          <Form.Group>
            <Form.Label htmlFor="first-name">First Name</Form.Label>
            <Form.Control
              required
              size="lg"
              type="text"
              name="first-name"
              onChange={handleChange}
            />
          </Form.Group>
        </Col>
        <Col md={6}>
          <Form.Group>
            <Form.Label htmlFor="last-name">Last Name</Form.Label>
            <Form.Control
              required
              size="lg"
              type="text"
              name="last-name"
              onChange={handleChange}
            />
          </Form.Group>
        </Col>
      </Row>
      <Row>
        <Col md={6}>
          <Form.Group>
            <Form.Label htmlFor="email">Email</Form.Label>
            <Form.Control
              required
              size="lg"
              type="email"
              name="email"
              onChange={handleChange}
            />
          </Form.Group>
        </Col>
        <Col md={6}>
          <Form.Group>
            <Form.Label htmlFor="phone">Phone (Optional)</Form.Label>
            <Form.Control
              size="lg"
              type="tel"
              name="phone"
              onChange={handleChange}
            />
          </Form.Group>
        </Col>
      </Row>
      <Row>
        <Col md={12}>
          <Form.Group>
            <Form.Label htmlFor="message">Message</Form.Label>
            <Form.Control
              required
              as="textarea"
              rows="3"
              placeholder="Enter your message here."
              name="message"
              onChange={handleChange}
            />
          </Form.Group>
        </Col>
      </Row>
      <Row>
        <Col md={12}>
          <FormControls>
            <Recaptcha
              ref={recaptchaRef}
              sitekey={RECAPTCHA_KEY}
              size="normal"
              id="recaptcha-google"
              onChange={() => setButtonDisabled(false)} // disable the disabled button!
              className="mb-3"
            />
            <div>
              <Button className="mr-3" type="reset" value="Eraser">
                Clear
              </Button>
              <Button type="submit" disabled={buttonDisabled}>
                Send
              </Button>
            </div>
          </FormControls>
        </Col>
      </Row>
    </Form>
  )
}
const FormControls = styled.div`
  display: flex;
  align-items: center;
  flex-direction: column;
  @media ${breakpoints.sm} {
    flex-direction: row;
    justify-content: space-between;
  }
  button[disabled] {
    cursor: not-allowed;
  }

gatsby-config:

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
})
module.exports = {
  siteMetadata: {
    title: `...`,
    description: `...`,
    author: `...`,
  },
  flags: {
    DEV_SSR: false,
  },
  plugins: [
    `gatsby-plugin-gatsby-cloud`,
    `gatsby-plugin-image`,
    `gatsby-plugin-sharp`,
    `gatsby-plugin-styled-components`,
    `gatsby-plugin-typography`,
    `gatsby-plugin-react-helmet`,
    `gatsby-transformer-sharp`,     
  },
}

HTML File in Static Folder:

<form
  data-netlify="true"
  name="contactVivaz"
  method="POST"
  data-netlify-honeypot="bot-field"
  data-netlify-recaptcha="true"
>
  <input type="text" name="first-name" />
  <input type="text" name="last-name" />
  <input type="email" name="email" />
  <input type="tel" name="phone" />
  <textarea name="message"></textarea>
  <div data-netlify-recaptcha="true"></div>
</form>
1

There are 1 answers

9
Ferran Buireu On

Your state management looks good, what it's mandatory is to have (and to check) the input value of hidden fields that must match exactly the form name in the JSX as well as in the Netlify's dashboard. Assuming that everything is well named, as it seems, I believe your issue comes from the Form component, which should looks like:

<Form
  name="contact"
  method="POST"
  action="/thank-you"
  data-netlify-honeypot="bot-field"
  data-netlify-recaptcha="true"
  data-netlify="true"
  onSubmit={handleSubmit}
>

Note the data-netlify-honeypot and data-netlify value.

For adding the reCAPTCHA field, you have two options:

  • Allowing Netlify to handle all the related logic by adding simply an empty <div> like:

        <div data-netlify-recaptcha="true"/>
    
  • Adding a custom reCAPTCHA (your case) what required to add the environment variables in your Netlify dashboard (prefixed with GATSBY_) and sending the response with the g-recaptcha-response field so your POST request needs to have that field as the docs suggest:

    The Netlify servers will check the submissions from that form, and accept them only if they include a valid g-recaptcha-response value.

Further references to base your setup: