Support Log in

51. Headless Forms via REST API

Developer Guide
Prefer video? Watch the Form Forge tutorials 9 short guides covering every feature Watch

Fetch a form’s definition over REST to render it in a headless frontend

(React, Vue, Next.js). Submission, however, does not go through REST.

> Submission is AJAX-only. POST /formforge/v1/forms/{id}/submit is not

> a public submission endpoint — it returns HTTP 501 Not Implemented. Real

> submissions go through the AJAX action formforge_submit (and its nopriv

> twin), which enforces a WordPress nonce, structural anti-spam (honeypot,

> timing, HMAC token), payment intents, and file uploads. A tokenless JSON POST

> cannot satisfy those guards, so it is intentionally rejected rather than

> silently accepting an unprotected submission. To submit programmatically,

> render the form with the

Form not found.

shortcode (which embeds the

> nonce + anti-spam tokens) and let its bundled script post to AJAX.

Fetching Form Data

javascript
// Fetch form definition from REST API (admin auth required)
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

Embed the shortcode so the rendered markup carries the nonce + anti-spam tokens,

then let Form Forge’s script handle the AJAX POST:

php
echo do_shortcode( '

Form not found.

' );

If you must drive submission from JavaScript, POST to admin-ajax.php with the

formforge_submit action and the nonce that the shortcode rendered into the

page — do not POST JSON to the REST /submit route (it returns 501).

Building a React Form Component (read-only render)

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();
        // Submission goes through admin-ajax.php (action "formforge_submit")
        // with the nonce rendered by the 

Form not found.

shortcode — NOT the REST // /submit route, which returns 501. See the note above. setMessage('Submit via the

Form not found.

shortcode / AJAX endpoint.'); }; 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> ); }

Forge AI Assistant Online

Hi! I'm the Form Forge AI assistant. Ask me anything about the plugin — setup, features, troubleshooting, or development.

Just now
Powered by Forge AI · Browse docs