Method B: JavaScript / SPA
Best for: React, Vue, Next.js, or custom websites using fetch() or Axios.
If you are building a Single Page Application (SPA), you likely want to handle the success message "inline" without redirecting the user away from your page. Because JavaScript intercepts the native browser submission, you must manually wire up the honeypot field.
Implementation Rules
- No API Keys: Do not send an
x-api-keyheader. Authentication is handled via your configured Allowed Domains. - The Honeypot Requirement: You must include the
website_urlhidden input in your HTML/JSX DOM. - Read from the DOM: Do not tie the honeypot to a React state
onChangehandler (bots bypass synthetic events). Instead, read the value directly from the DOM upon submission.
Example React Implementation
// 1. The Submit Handler
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
// Extract values, including the dynamic honeypot directly from the DOM
const email = formData.get('email');
const firstName = formData.get('first_name');
const websiteUrl = formData.get('website_url');
try {
const response = await fetch("[https://app.gordoncrm.com/api/forms/YOUR_FORM_ID](https://app.gordoncrm.com/api/forms/YOUR_FORM_ID)", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
email: email,
first_name: firstName,
website_url: websiteUrl // ⚠️ HONEYPOT: Pass the dynamic DOM value here
})
});
if (response.ok) {
// Handle your inline success state here (e.g., show a green checkmark)
}
} catch (error) {
console.error("Submission failed", error);
}
};
// 2. The JSX/HTML
return (
<form onSubmit={handleSubmit}>
<input type="email" name="email" required />
<input type="text" name="first_name" />
{/* Honeypot — Hidden visually and from 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>
);