← All frameworks

CMS

WordPress form handling without a backend

Most WordPress form plugins store submissions in your own database and email through your host — which means you own the personal data, the spam, and the GDPR exposure. If you would rather not, you can embed a plain HTML form that posts to Formward, an EU-hosted form backend, and skip the plugin's data store entirely. The submissions live in the EU, not in wp_postmeta.

The cleanest route is a Custom HTML block (Gutenberg) or a Classic Editor HTML view: paste the markup below and you are done. If you prefer a shortcode, register a tiny one in your theme's functions.php that returns the same HTML, so editors can drop [formward_contact] into any page.

EU-hosted · Run WordPress wherever you like while contact data is collected and stored in Sweden — an easy GDPR win without a heavyweight forms plugin.

The WordPress example

Copy this into your project and replace <FORM_ID> with the id of a form you create in the Formward dashboard.

html

<!-- Paste into a Custom HTML block, or return from a shortcode. -->
<form action="https://forms.formward.eu/f/<FORM_ID>" method="POST">
  <p>
    <label>Email<br />
      <input type="email" name="email" required />
    </label>
  </p>
  <p>
    <label>Message<br />
      <textarea name="message" required></textarea>
    </label>
  </p>
  <!-- Honeypot: leave empty. -->
  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
    style="display:none" aria-hidden="true" />
  <p><button type="submit">Send</button></p>
</form>

<!-- Optional shortcode — add to your theme's functions.php: -->
<?php
function formward_contact_shortcode() {
  ob_start(); ?>
  <form action="https://forms.formward.eu/f/<FORM_ID>" method="POST">
    <input type="email" name="email" required />
    <textarea name="message" required></textarea>
    <input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
      style="display:none" aria-hidden="true" />
    <button type="submit">Send</button>
  </form>
  <?php return ob_get_clean();
}
add_shortcode("formward_contact", "formward_contact_shortcode");
?>

Success and error handling

  • A plain HTML POST needs no JavaScript: WordPress serves the page, the browser submits to Formward, and Formward returns a 302 redirect (or your thank-you page).
  • Keep the form in a Custom HTML block — the visual editor will not strip the markup the way it can with pasted-in code elsewhere.
  • Because nothing is stored in WordPress, a database breach or a vulnerable plugin cannot leak the form submissions; they only exist in Formward.

Spam protection

Every example above includes the _gotcha honeypot field. It is hidden from real users and must stay empty; Formward silently drops any submission where it is filled, which stops most bots with no CAPTCHA. For a stricter gate, add a Cloudflare Turnstile widget and send its token as the cf-turnstile-response field — Formward verifies it on receipt.

The JSON response

A standard POST gets a 302 redirect (or your thank-you page). Send the Accept: application/json header — as every fetch() example above does — and Formward returns JSON instead:

HTTP/1.1 200 OK
Content-Type: application/json

{ "ok": true, "id": "clxyz123...", "files": [] }

On failure the body is { ok: false, error } with a 4xx status (validation, plan limit, and so on). See the AJAX docs for the full status-code table and CORS notes.

Other frameworks

Collect your first WordPress submission

Create a form, paste the snippet, and keep every submission in the EU. GDPR-clean from the first POST.

WordPress form handling without a backend | Formward