Add a React contact form that emails you without a backend
A React contact form doesn't need a server of its own. This component reads its fields with FormData, posts JSON to FormThunder and tracks sending, sent and error states in useState. Submissions are stored and emailed to your verified address. Your AI can drop it in for you: get_snippet returns this code with your key filled in.
Updated
The React code
import { useState } from "react";
export default function ContactForm() {
const [status, setStatus] = useState("idle");
async function handleSubmit(event) {
event.preventDefault();
const form = event.currentTarget;
setStatus("sending");
try {
const response = await fetch("https://formthunder.com/submit", {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({
...Object.fromEntries(new FormData(form)),
access_key: "YOUR_ACCESS_KEY",
subject: "New message from the website",
}),
});
const data = await response.json();
setStatus(data.success ? "sent" : "error");
if (data.success) form.reset();
} catch {
setStatus("error");
}
}
if (status === "sent") return <p role="status">Thanks, we got your message.</p>;
return (
<form onSubmit={handleSubmit}>
<input type="checkbox" name="botcheck" style={{ display: "none" }} tabIndex={-1} />
<label htmlFor="name">Name</label>
<input id="name" name="name" required />
<label htmlFor="email">Email</label>
<input id="email" name="email" type="email" required />
<label htmlFor="message">Message</label>
<textarea id="message" name="message" rows={5} required />
<button disabled={status === "sending"}>
{status === "sending" ? "Sending..." : "Send"}
</button>
{status === "error" && <p role="alert">That didn't send. Please try again.</p>}
</form>
);
}Replace YOUR_ACCESS_KEY with your free key. It's public by design, so it's safe in client code.
Notes for React
- Keep
formin a variable before the firstawait. React clearsevent.currentTargetonce the handler has yielded. - Uncontrolled inputs are enough here. You don't need a
useStateper field unless you validate as the visitor types. - Read the key from your build tool's env if you prefer, such as
import.meta.env.VITE_FORMTHUNDER_KEY. It's public either way, so this is about tidiness.
Or have your AI add it
Connect the MCP server, then ask. The agent creates the form and writes the code for you, and it can send a real test when it's done.
Add a FormThunder contact form to this React site that emails hello@example.com. Send a test when you're done.Questions
Do I need React Hook Form or Formik?
Not for this. They're useful for long forms with live validation, and you can call the same fetch from their submit handlers.
Does this work with React 19 form actions?
Yes. Use the same fetch inside your action function, and read the fields from the FormData it receives.
Get your React form sending
The free plan covers 250 submissions a month, with MCP, the CLI and the brand kit included.