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>
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);
});
}