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
- Configure your form's Allowed Domains in the Gordon CRM dashboard (add the domain where your SPA is hosted).
- Include the honeypot input in your JSX/HTML DOM.
- 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"),
\};