Search code examples
javascriptapipostnext.jscontact-form-7

Next.js getting validation failed sending form data to contact form 7 API


I am trying to send data to the Contact Form 7 API but get an error when sending the form:

{into: "#", status: "validation_failed", message: "One or more fields have an error. Please check and try again.", posted_data_hash: "", invalid_fields:

The input fields on the form have all the correct name values e.g. name="your-name"

I am sending form data like so:

  async function handleSubmit(e) {
    e.preventDefault();

    const formData = {};

    Array.from(e.currentTarget.elements).forEach((field) => {
      if (!field.name) return;
      formData[field.name] = field.value;
    });

    await fetch(
      "https://domain.tld/cms/wp-json/contact-form-7/v1/contact-forms/1234/feedback",
      {
        body: JSON.stringify(formData),
        headers: {
          "content-type": "multipart/form-data",
        },
        method: "POST",
      }
    )
      .then((response) => response.json())
      .then((data) => {
        console.log(data);
      })
      .catch((error) => {
        console.error("Error:", error);
      });
  }

I've tried it in Postman and it works and get status message send. I have no idea what I am doing wrong here.

Here's the form:

<Form onSubmit={handleSubmit}>
    <Form.Group controlId="your-name">
      <Form.Control
        required
        type="text"
        placeholder="Your name"
        name="your-name"
      />
      <Form.Control.Feedback type="invalid">
        Please enter your name
      </Form.Control.Feedback>
    </Form.Group>
    <Form.Group controlId="your-email">
      <Form.Control
        required
        type="email"
        placeholder="Your email address"
        name="your-email"
      />
      <Form.Control.Feedback type="invalid">
        Please enter your email
      </Form.Control.Feedback>
    </Form.Group>
    <Form.Group controlId="your-message">
      <Form.Control
        as="textarea"
        cols={30}
        rows={6}
        placeholder="Write your message..."
        name="your-message"
      />
    </Form.Group>
    <Button
      type="submit"
      variant="primary"
      size="lg"
    >
      Send Message
      <span></span>
    </Button>
  </Form>

Solution

  • If you are using any Content-Type that starts with multipart/* you have to set the boundary, and there’s no boundary in your code.

    To overcome that, just use FormData class like const formData = new FormData() and append values like formData.append(key, value) that way you will have a FormData instance so Axios can figure out what kind of a data you send, and it can set the Content-Type automatically with boundary.

    Here’s the code that should work, I haven’t tested it though:

    async function handleSubmit(e) {
      e.preventDefault();
    
      const formData = new FormData();
    
      Array.from(e.currentTarget.elements).forEach((field) => {
        if (!field.name) return;
        formData.append(field.name, field.value);
      });
    
      await fetch(
        "https://domain.tld/cms/wp-json/contact-form-7/v1/contact-forms/1234/feedback",
        {
          body: formData,
          method: "POST",
        }
      )
        .then((response) => response.json())
        .then((data) => {
          console.log(data);
        })
        .catch((error) => {
          console.error("Error:", error);
        });
    }