Build Phases
Phase 4 — Forms & Submissions
Contact Form 7 integration via the WordPress REST API.
Find Your Form ID
In WordPress admin, go to Contact → Contact Forms. Click your form — the URL will show ?post=123. That number is your Form ID.
Contact Form Component
// src/components/ContactForm.tsx
"use client";
import { useState } from "react";
// Replace YOUR_FORM_ID with the numeric ID from CF7 admin URL (?post=123)
const CF7_URL = `${process.env.NEXT_PUBLIC_WP_API_URL
?.replace("/wp/v2","")}/contact-form-7/v1/contact-forms/YOUR_FORM_ID/feedback`;
export default function ContactForm() {
const [status, setStatus] = useState<"idle"|"loading"|"success"|"error">("idle");
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setStatus("loading");
const formData = new FormData(e.currentTarget);
try {
const res = await fetch(CF7_URL, { method: "POST", body: formData });
const result = await res.json();
setStatus(result.status === "mail_sent" ? "success" : "error");
} catch {
setStatus("error");
}
}
return (
<form onSubmit={handleSubmit}>
<input type="text" name="your-name" placeholder="Your Name" required />
<input type="email" name="your-email" placeholder="Email" required />
<textarea name="your-message" placeholder="Message" required />
<button type="submit" disabled={status === "loading"}>
{status === "loading" ? "Sending..." : "Send Message"}
</button>
{status === "success" && <p>Message sent!</p>}
{status === "error" && <p>Something went wrong. Please try again.</p>}
</form>
);
}The CF7 endpoint path is /wp-json/contact-form-7/v1/contact-forms/ID/feedback — not the standard /wp/v2/ path. Replace ID with the numeric ID from the CF7 admin URL.
Matching Field Names
The name attribute on each input must match exactly what you set in the CF7 form editor in WordPress. Mismatched names are the most common cause of silent failures.
| CF7 Field Tag | HTML name attribute |
|---|---|
[text your-name] | name="your-name" |
[email your-email] | name="your-email" |
[textarea your-message] | name="your-message" |
API Response Statuses
| Status | Meaning |
|---|---|
mail_sent | Form submitted and email sent successfully |
mail_failed | Form valid but email failed to send — check SMTP settings |
validation_failed | Required fields missing or invalid |
spam | Flagged by Akismet or honeypot |
Test your form submission directly in the terminal first: curl -X POST "https://cms.yourdomain.com/wp-json/contact-form-7/v1/contact-forms/123/feedback" -F "your-name=Test" -F "your-email=test@test.com" -F "your-message=Hello"