The form
Replace YOUR-ACCESS-KEY with the key from your form's page. The highlighted line is the one that points the form at Formwire.
1// src/ContactForm.jsx2import { useState } from "react";34export function ContactForm() {5const [status, setStatus] = useState("idle");67async function onSubmit(e) {8e.preventDefault();9setStatus("sending");10const body = new FormData(e.currentTarget);11body.append("access_key", "YOUR-ACCESS-KEY");12const res = await fetch("https://formwire.io/submit", {13method: "POST",14headers: { Accept: "application/json" },15body,16});17const { success } = await res.json();18setStatus(success ? "sent" : "error");19}2021if (status === "sent") return <p>Thanks, your message is on its way.</p>;2223return (24<form onSubmit={onSubmit}>25<input type="text" name="fax" tabIndex={-1} autoComplete="off" style={{ display: "none" }} />26<label htmlFor="name">Name</label>27<input id="name" name="name" type="text" required />28<label htmlFor="email">Email</label>29<input id="email" name="email" type="email" required />30<label htmlFor="message">Message</label>31<textarea id="message" name="message" rows={5} required />32<button type="submit" disabled={status === "sending"}>33{status === "sending" ? "Sending" : "Send"}34</button>35{status === "error" && <p>Something went wrong. Please try again.</p>}36</form>37);38}
Steps
- 1
Create a form and copy its access key
Sign up at app.formwire.com and create a form. Your sign-in address receives its submissions from the start. The access key is on the form's Settings tab, under General.
- 2
Add the component
Create src/ContactForm.jsx with the code above and replace YOUR-ACCESS-KEY with your key. FormData reads every named field from the form, so adding an input is adding one line of JSX.
- 3
Render it
Import the component wherever the contact form belongs. It owns its own state, so nothing else in the app changes.
jsx 1
import { ContactForm } from "./ContactForm";23export default function App() {4return (5<main>6<h1>Contact</h1>7<ContactForm />8</main>9);10} - 4
Send a test submission
Open the app in your browser, fill the form in and send it. The submission appears in the form's inbox in the dashboard within a few seconds and the notification email follows, with Reply-To set to the address the visitor typed.
Notes for React
- With the Accept: application/json header Formwire answers with JSON: { success: true, message, data: { submission_id } } on success, and { success: false, message } on an error. Show message to the visitor when success is false.
- Send JSON instead of FormData if you prefer: set Content-Type to application/json and include access_key in the body. File uploads need FormData.
- The component uses React's onSubmit with preventDefault, so the browser never navigates. Drop both and give the form an action attribute if you would rather redirect to a thank-you page.
Questions
Can I use react-hook-form or Formik with this?
Yes. Build the FormData or a JSON object from the library's values in its submit handler and post it to the same endpoint with access_key included. Nothing about the endpoint changes.
Is the access key safe to put in client-side code?
Yes. The access key is a public ID that can only deliver submissions to the inbox you verified. It cannot read submissions or change settings, and you can rotate it from the form's settings if it is ever abused.
How does the form stop spam without a captcha?
The hidden fax field is a honeypot: a submission that fills it in goes to the Spam folder and nobody is emailed. A spam filter and rate limits also run on every form. Settings, Spam & security has the filter level, and on Pro, allowed domains.
Where do submissions go?
Each submission is stored in the form's inbox in the dashboard and emailed to you with Reply-To set to the visitor. On Pro it can also go to more recipients and to webhooks. The inbox exports to CSV and JSON.