Skip to content

About

SubmitDock (formerly Headless Form): a self-hosted headless form backend for WordPress. Send any form from a static site, React, Next.js, Vue, or a mobile app to a REST API endpoint; submissions are saved in WordPress and emailed to you.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

7 Commits

Folders and files

Repository files navigation

SubmitDock

Formerly Headless Form. Renamed to SubmitDock in 1.1.0; the REST endpoint is now /wp-json/submitdock/v1/submit.

A self-hosted form backend for WordPress. Send any form from a static site, a headless front end (React, Next.js, Vue, Astro, Gatsby), a mobile app, or a server to a REST API endpoint. Every submission is saved in WordPress and emailed to you.

Tested up to WordPress 7.1 PHP 7.4 to 8.5 License GPLv2 or later

No form builder and no field setup: build the form however you like, and the endpoint accepts whatever fields it sends. Think Formspree or Netlify Forms, running on your own WordPress site with no submission limits.

Features

  • Any fields: text, numbers, booleans, arrays for checkbox groups, and nested objects. Up to 50 fields per submission.
  • JSON or HTML form posts: fetch with JSON, or a plain <form action="…" method="post"> that redirects back to a thank-you page.
  • Named forms: /submit/newsletter, /submit/quote, and so on, filterable in the dashboard.
  • Email notifications with Reply-To set to the sender.
  • Allowed websites: CORS and an origin check restrict which websites can submit.
  • Spam protection: a configurable honeypot field, a per-IP rate limit, and optional Cloudflare Turnstile, hCaptcha, or Google reCAPTCHA (v2/v3) checks, verified server-side.
  • Akismet and a Spam folder: with the Akismet plugin connected, suspected spam is kept in a Spam folder without an email. Spam / Not spam actions report back to Akismet, and old spam is purged daily (30 days by default).
  • API key for server-side code: send X-SubmitDock-Key from a Next.js server action, an API route, or an app backend. Keyed requests skip the origin check, CAPTCHA, and rate limit.
  • Dashboard inbox with CSV export.
  • Privacy: WordPress personal data export and erasure by email address, optional IP storage, and optional IP geolocation (off by default).
  • Hooks to validate fields, forward submissions to a CRM, Slack, or webhook, and customize the email.

Quick start

  1. Install and activate the plugin (upload the folder to wp-content/plugins, or download the ZIP from Releases).
  2. Go to Form Submissions → Settings, set the notification email, and add your front-end origin, for example https://example.com.
  3. Post a form:
const response = await fetch("https://your-site.com/wp-json/submitdock/v1/submit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Jane",
    email: "[email protected]",
    message: "Hello",
    _gotcha: "", // spam trap: always empty for real visitors
    __context: { page_url: location.href, referrer: document.referrer },
  }),
});
const { message } = await response.json(); // ready to show the visitor

Or without JavaScript:

<form action="https://your-site.com/wp-json/submitdock/v1/submit/contact" method="post">
  <input name="name" required>
  <input name="email" type="email" required>
  <textarea name="message" required></textarea>
  <input name="_gotcha" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px" aria-hidden="true">
  <input type="hidden" name="__redirect" value="https://example.com/thank-you/">
  <button>Send</button>
</form>

The Developer guide screen in the dashboard shows these examples with your own endpoint URL.

API

Endpoint POST /wp-json/submitdock/v1/submit or /submit/{form} (a-z0-9_-, up to 64 characters)
Body JSON object, application/x-www-form-urlencoded, or multipart/form-data (no files)
Reserved keys __context (page_url, referrer; with the API key also ip_address, user_agent), __redirect (HTML forms), __captcha, the CAPTCHA widget fields (cf-turnstile-response, h-captcha-response, g-recaptcha-response), and the honeypot field. Keys starting with __ and CAPTCHA tokens are never saved.
Auth None for browsers (origin allow-list). Server-side: X-SubmitDock-Key: <key> from Settings; the key is shown once and stored as a SHA-256 hash.
Limits 50 fields, 20,000 bytes, 5,000 characters per text value, 100 items per array, 5 levels of nesting
Status Meaning
200 Saved and emailed: {"success": true, "message": "…", "email_status": "sent"}
202 Saved, email failed (email_status: "failed"). Treat as success.
400 Invalid data, spam trap filled, or CAPTCHA check failed
403 Origin not allowed and no valid API key. Server-to-server requests send no Origin, so use the API key.
429 Rate limit reached

Hooks

// Reject or modify fields before saving.
add_filter( 'submitdock_fields', function ( $fields, $request ) {
	if ( empty( $fields['email'] ) ) {
		return new WP_Error( 'missing_email', 'Please enter your email.', array( 'status' => 400 ) );
	}
	return $fields;
}, 10, 2 );

// Forward to a webhook after saving.
add_action( 'submitdock_submission_saved', function ( $post_id, $fields, $form, $visitor ) {
	wp_remote_post( 'https://hooks.example.com/forms', array( 'body' => wp_json_encode( $fields ), 'blocking' => false ) );
}, 10, 4 );

Also available: submitdock_email (change the notification), submitdock_client_ip (read the real IP behind a proxy or CDN), and submitdock_submission_spam (fires when a submission is saved to the Spam folder).

Suspected spam (Akismet, or a CAPTCHA service that could not be reached) is saved with the submitdock_spam post status and no email, and the sender receives the normal success response.

Project structure

submitdock.php                         Plugin header and bootstrap
includes/class-submitdock-api.php      REST route, validation, rate limit, API key, notification email
includes/class-submitdock-spam.php     CAPTCHA verification, Akismet, Spam folder and daily purge
includes/class-submitdock-submissions.php  Submission post type, inbox columns, CSV export
includes/class-submitdock-settings.php Settings defaults and validation
includes/class-submitdock-admin.php    Settings screen and developer guide
includes/class-submitdock-privacy.php  Privacy policy text, data export and erasure
assets/                                            Developer guide styles and copy buttons
uninstall.php                                      Removes settings (and submissions if opted in)
readme.txt                                         WordPress.org readme

Custom development

Need file uploads, CRM integration, multi-step forms, or a full headless WordPress build? The plugin is built and maintained by Ali Nawaz, a WordPress and full stack developer. Get in touch for custom work.

License

GPLv2 or later. See LICENSE.

About

SubmitDock (formerly Headless Form): a self-hosted headless form backend for WordPress. Send any form from a static site, React, Next.js, Vue, or a mobile app to a REST API endpoint; submissions are saved in WordPress and emailed to you.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages