HTML, React & Next.js Form Ingestion Guide
Every FormFork endpoint (POST /f/{formId}) accepts standard application/x-www-form-urlencoded, multipart/form-data, and application/json requests without server boilerplate.
- Send POST requests to https://formfork.io/f/{formId} using standard HTML <form>, fetch(), Axios, or cURL.
- Include the header Accept: application/json for headless JSON responses, or omit it to trigger automatic browser thank-you/redirect flows.
- Include a hidden _gotcha field in every form to enable zero-friction honeypot bot quarantine.
- Auto-provision endpoints from static sites or AI-generated apps via POST /api/v1/submit with an ff_pub_ token.
1. Standard HTML Form POST (Browser Redirect Flow)
Point any native HTML <form> element to your FormFork endpoint URL using method="POST". When submitted without an Accept: application/json header, FormFork validates the payload, stores the submission, and redirects the user to your configured Thank-You URL or hosted confirmation screen.
<form action="https://formfork.io/f/{form_id}" method="POST">
<label for="name">Full Name</label>
<input id="name" type="text" name="name" placeholder="Jane Doe" required />
<label for="email">Work Email</label>
<input id="email" type="email" name="email" placeholder="jane@acmecorp.io" required />
<label for="message">Project Scope</label>
<textarea id="message" name="message" placeholder="Tell us about your timeline..." required></textarea>
<!-- Honeypot Bot Protection (Keep hidden and empty) -->
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" />
<button type="submit">Submit Inquiry</button>
</form>2. React & Next.js Async JSON Fetch (Headless Mode)
For single-page applications (React, Next.js App Router, Vue, Svelte, Astro), send a POST request with Content-Type: application/json and Accept: application/json. FormFork responds with a structured JSON payload containing the newly created submissionId.
'use client';
import { useState } from 'react';
export default function ContactForm({ formId = 'form-contact-demo' }: { formId?: string }) {
const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
const [submissionId, setSubmissionId] = useState<string | null>(null);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setStatus('submitting');
const formData = new FormData(e.currentTarget);
const payload = {
...Object.fromEntries(formData.entries()),
_gotcha: '',
};
const res = await fetch(`https://formfork.io/f/${formId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify(payload),
});
const data = await res.json();
if (res.ok && data.success) {
setSubmissionId(data.submissionId);
setStatus('success');
e.currentTarget.reset();
} else {
setStatus('error');
}
}
return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="Jane Doe" required />
<input name="email" type="email" placeholder="jane@company.com" required />
<textarea name="message" placeholder="How can we help?" required />
<input type="text" name="_gotcha" style={{ display: 'none' }} tabIndex={-1} autoComplete="off" />
<button type="submit" disabled={status === 'submitting'}>
{status === 'submitting' ? 'Sending...' : 'Send Message'}
</button>
{status === 'success' && <p>Submitted! Reference ID: {submissionId}</p>}
</form>
);
}3. cURL Command-Line Endpoint Verification
Verify your endpoint configuration, schema validation rules, and webhook triggers directly from your terminal using cURL.
curl -X POST "https://formfork.io/f/{form_id}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Alex Rivera",
"email": "alex@enterprise.io",
"inquiry_type": "Enterprise Partnership",
"message": "Testing headless form endpoint via cURL",
"_gotcha": ""
}'
# HTTP/1.1 200 OK
# {
# "success": true,
# "message": "Form submitted successfully",
# "submissionId": "sub-1729624800-k4m9p"
# }4. Supported Content-Types & Response Behavior
FormFork automatically inspects incoming Content-Type and Accept headers to determine how to parse the body and format the HTTP response.
| Request Content-Type | Accept Header | Use Case | Response Format |
|---|---|---|---|
| application/x-www-form-urlencoded | text/html (Default) | Standard HTML <form method="POST"> | 302 Redirect or HTML Thank-You Page |
| application/json | application/json | React, Next.js, Vue, Astro fetch() | 200 OK JSON { success, submissionId } |
| multipart/form-data | application/json | File uploads & binary attachments | 200 OK JSON with attached file metadata |
Frequently Asked Technical Questions
Can I submit forms from a static site hosted on Vercel, Netlify, or GitHub Pages?
Yes. FormFork endpoints are designed for static and Jamstack sites. Simply point your HTML form action or fetch() request to https://formfork.io/f/{formId} and add your production domain to the form CORS allowlist if domain restriction is enabled.
How do I prevent page reloads when submitting a form?
Submit the form using JavaScript fetch() and include the header Accept: application/json. FormFork will return a JSON object ({ success: true, submissionId }) instead of performing a browser redirect.
Does FormFork require me to pre-define fields before receiving submissions?
You can either enforce a strict schema created in the Visual Form Studio or submit dynamic key-value fields directly to your endpoint.