Render and submit forms from a headless frontend (React, Vue, Next.js) using the REST API.
Fetching Form Data
javascript
// Fetch form definition from REST API
const response = await fetch( 'https://example.com/wp-json/formforge/v1/forms/1', {
headers: { 'Authorization': 'Basic ' + btoa( 'admin:XXXX XXXX' ) }
} );
const form = await response.json();
// Render fields dynamically in React/Vue
form.fields.forEach( field => {
// Build your own UI components based on field.type, field.label, etc.
} );Submitting from a Headless Frontend
javascript
// Submit via the REST API
const payload = {
form_id: 1,
fields: {
field_1: 'John Doe',
field_2: '[email protected]',
field_3: 'Hello from the headless frontend!',
}
};
const result = await fetch( 'https://example.com/wp-json/formforge/v1/forms/1/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify( payload ),
} );Building a React Form Component
javascript
function FormForgeHeadless({ formId, apiBase }) {
const [form, setForm] = React.useState(null);
const [values, setValues] = React.useState({});
const [message, setMessage] = React.useState('');
React.useEffect(() => {
fetch(`${apiBase}/wp-json/formforge/v1/forms/${formId}`, {
headers: { 'Authorization': 'Basic ' + btoa('admin:XXXX') }
})
.then(r => r.json())
.then(setForm);
}, [formId]);
const handleSubmit = async (e) => {
e.preventDefault();
const res = await fetch(`${apiBase}/wp-json/formforge/v1/forms/${formId}/submit`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ form_id: formId, fields: values }),
});
const data = await res.json();
setMessage(data.success ? form.settings.success_message : data.message);
};
if (!form) return <p>Loading...</p>;
return (
<form onSubmit={handleSubmit}>
{form.fields.map(field => (
<div key={field.id}>
<label>{field.label}</label>
<input
type={field.type === 'textarea' ? undefined : field.type}
required={field.required}
placeholder={field.placeholder}
onChange={e => setValues({...values, [field.id]: e.target.value})}
/>
</div>
))}
<button type="submit">{form.settings.submit_text}</button>
{message && <p>{message}</p>}
</form>
);
}—