React works well with Formbase because you can choose between native form posts or programmatic submissions. Use native posts for the simplest setup, and use fetch when you need full UI control.
The examples below use fetch with redirect: 'manual' to avoid following the Formbase redirect in the browser.
Create your form UI
Build the form as usual and give each input a name attribute.
Submit to Formbase
Basic submission
File upload
import { useState } from 'react';
export default function ContactForm() {
const [status, setStatus] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
setStatus('');
setIsSubmitting(true);
const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
method: 'POST',
body: new FormData(event.currentTarget),
redirect: 'manual',
});
if (response.status === 303 || response.ok) {
setStatus('Submitted!');
event.currentTarget.reset();
} else {
setStatus('Submission failed.');
}
setIsSubmitting(false);
};
return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="Name" required />
<input name="email" type="email" placeholder="Email" required />
<textarea name="message" required />
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Sending...' : 'Send'}
</button>
{status && <p>{status}</p>}
</form>
);
}
The FormData API serializes the form exactly like a normal browser post.import { useState } from 'react';
export default function UploadForm() {
const [status, setStatus] = useState('');
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
method: 'POST',
body: new FormData(event.currentTarget),
redirect: 'manual',
});
setStatus(response.status === 303 || response.ok ? 'Uploaded!' : 'Failed');
};
return (
<form onSubmit={handleSubmit} encType="multipart/form-data">
<input name="resume" type="file" />
<button type="submit">Upload</button>
{status && <p>{status}</p>}
</form>
);
}
Add encType="multipart/form-data" when your form includes file inputs.
Browser submissions return a 303 redirect. Treat that as success in client-side code, or post from your server for a JSON response.