FormDexSecure form operations
Try FormDex
FormDexSecure form operations

A product by MeshDex

FormDex is a secure form operations platform for collecting, validating, and routing website submissions. Manage protected endpoints, email notifications, webhook delivery, and submission history from one reliable workspace.

Product

PlatformPricingDocumentation

Access

LoginRegisterReset password

Legal

Privacy PolicyTerms of ServiceRefund PolicyContact Us
  1. Home
  2. Documentation
  3. Integration
  4. Connect a React form
Docs home

Integration guide

Connect a React form

Build an accessible React form with an explicit honeypot, predictable pending state, useful errors, and a submission path that matches your security model.

Step by step

1

Render semantic controls

Use a real form and named inputs so FormData, browser validation, keyboard submission, and assistive technology work normally.

2

Add the honeypot

Keep it inside the form but outside the visible layout. aria-hidden removes the wrapper from the accessibility tree; tabIndex prevents keyboard focus.

3

Submit FormData

Use new FormData(event.currentTarget). Do not manually set Content-Type because the browser supplies the multipart boundary.

4

Manage pending and errors

Disable repeat submission while pending, announce errors with role=alert, and reset only after response.ok.

5

Choose direct or server-mediated delivery

Direct browser delivery is simplest and relies on allowed origins, captcha, and rate limiting. A React framework server route can keep the API key private and must validate the honeypot before proxying.

6

Run a production test

Verify success, a deliberately filled honeypot rejection, captcha behavior, and notification/webhook delivery from the real hostname.

Honeypot in this integration

Where it belongs and who validates it

Render the honeypot as an uncontrolled text input inside the React form. Use the exact FormDex field name, tabIndex={-1}, autoComplete="off", and an off-screen wrapper. Do not store or populate its value in component state; FormData includes it automatically as an empty string.

Read the honeypot fundamentals →

Working example

Complete React component

import { useState } from "react";

export function ContactForm() {
  const [status, setStatus] = useState("idle");
  const [error, setError] = useState("");

  async function handleSubmit(event) {
    event.preventDefault();
    const form = event.currentTarget;
    setStatus("submitting");
    setError("");

    try {
      const response = await fetch("https://YOUR_FORMDEX_DOMAIN/api/forms/FORM_ID", {
        method: "POST",
        headers: { "X-API-Key": "YOUR_API_KEY" },
        body: new FormData(form)
      });
      const result = await response.json();
      if (!response.ok) throw new Error(result.message || result.error || "Submission failed");
      form.reset();
      setStatus("success");
    } catch (requestError) {
      setError(requestError.message);
      setStatus("error");
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      {/* HONEYPOT: exact FormDex field name; keep empty and off-screen. */}
      <div aria-hidden="true" style={{ position: "absolute", left: "-10000px", width: 1, height: 1, overflow: "hidden" }}>
        <label>Leave this field empty
          <input type="text" name="company" tabIndex={-1} autoComplete="off" />
        </label>
      </div>

      <label>Email <input type="email" name="email" required /></label>
      <label>Message <textarea name="message" required /></label>
      <label>Attachments <input type="file" name="attachments" accept=".pdf,.jpg,.jpeg,.png" multiple /></label>
      {error ? <p role="alert">{error}</p> : null}
      {status === "success" ? <p role="status">Enquiry sent.</p> : null}
      <button type="submit" disabled={status === "submitting"}>
        {status === "submitting" ? "Sending…" : "Send enquiry"}
      </button>
    </form>
  );
}

Troubleshooting

Honeypot always triggers

Remove controlled values, placeholders, and autofill from the honeypot input; it must submit an empty string.

CORS error

Add the deployed React origin exactly, including scheme and port where applicable.

State updates but no submission

Confirm the handler uses the form’s onSubmit event and the button has type=submit.

Captcha failure

Render the configured provider widget and obtain a fresh token for every attempt.

Before you start

  • • A FormDex endpoint and API key
  • • The React app’s full HTTPS origin saved in FormDex
  • • Field names matching the configured schema
  • • Captcha widget integration when protection is enabled

Production notes

  • • Replace company if the FormDex Access setting uses another honeypot name.
  • • When captcha is enabled, include the provider widget inside the form so FormData carries its response token.
  • • For Next.js or another full-stack React framework, prefer a server route when keeping the FormDex API key out of browser source is a requirement.
View the complete integration overview →