Forms API
React / SPA

React / SPA

For React, Vue, Next.js, or any application using fetch() or Axios.

This method uses JavaScript to submit the form data via fetch(), allowing you to handle the success state inline without redirecting the user away from the page. Because JavaScript intercepts the native browser submission, the honeypot field must be wired up manually.

Setup

  1. Configure your form's Allowed Domains in the Gordon CRM dashboard (add the domain where your SPA is hosted).
  2. Include the honeypot input in your JSX/HTML DOM.
  3. Read the honeypot value from the DOM on submission (do not bind it to React state).

Code Example

const handleSubmit = async (e) => \{
  e.preventDefault();
  const formData = new FormData(e.currentTarget);
 
  const payload = \{
    email: formData.get("email"),
    first_name: formData.get("first_name"),
    last_name: formData.get("last_name"),
    website_url: formData.get("website_url"), // Honeypot: pass the DOM value
  \};
 
  try \{
    const response = await fetch(
      "https://app.gordoncrm.com/api/forms/YOUR_FORM_ID",
      \{
        method: "POST",
        headers: \{ "Content-Type": "application/json" \},
        body: JSON.stringify(payload),
      \}
    );
 
    if (response.ok) \{
      // Handle inline success (e.g., show confirmation message)
    \}
  \} catch (error) \{
    console.error("Submission failed", error);
  \}
\};
 
return (
  <form onSubmit=\{handleSubmit\}>
    <input type="email" name="email" placeholder="Email" required />
    <input type="text" name="first_name" placeholder="First Name" />
    <input type="text" name="last_name" placeholder="Last Name" />
 
    \{/* Honeypot — hidden from users and screen readers */\}
    <div style=\{\{ position: "absolute", left: "-9999px" \}\} aria-hidden="true">
      <input type="text" name="website_url" tabIndex=\{-1\} autoComplete="off" />
    </div>
 
    <button type="submit">Submit</button>
  </form>
);

Important Notes

No API Key Required

Do not send an x-api-key header from browser code. Authentication is handled automatically via the Origin header and your configured allowed domains.

Honeypot: Read from the DOM

Do not bind the website_url field to a React state variable with onChange. Bots can bypass synthetic React events. Instead, include the input in the DOM and read its value via FormData on submission (as shown above).

CORS

The API returns dynamic CORS headers based on your form's allowed domains configuration. If your domain is correctly whitelisted, fetch() requests will work without any additional CORS configuration on your end.

Success Handling

Since success_redirect_url is designed for HTML forms, SPA integrations typically leave it empty and handle the response inline. The API returns:

\{ "success": true, "contact_id": "..." \}

Optional Fields

You can include any of the supported submission fields in your payload. For example:

const payload = \{
  email: formData.get("email"),
  first_name: formData.get("first_name"),
  last_name: formData.get("last_name"),
  phone: formData.get("phone"),
  is_subscribed: formData.get("is_subscribed") === "on",
  notes: formData.get("notes"),
  website_url: formData.get("website_url"),
\};