Submit forms with JavaScript (fetch)

Submit to SiteBackend with fetch - send JSON or FormData, read the JSON response, and show success or error messages without a page reload.

1 minUpdated

Use fetch when you want to stay on the page and show your own success message. Ask for JSON and the endpoint answers with { "ok": true } instead of redirecting.

Send the form with FormData

This keeps your existing HTML form and works with any number of fields.

contact.html
<form id="contact" action="https://api.sitebackend.com/forms/YOUR_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" />
  <button type="submit">Send</button>
  <p id="status" role="status"></p>
</form>
 
<script>
  const form = document.getElementById("contact");
  const status = document.getElementById("status");
 
  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    status.textContent = "Sending…";
    const res = await fetch(form.action, {
      method: "POST",
      body: new FormData(form),
      headers: { Accept: "application/json" },
    });
    const result = await res.json();
    if (result.ok) {
      form.reset();
      status.textContent = "Thanks! We'll be in touch.";
    } else {
      status.textContent = result.error;
    }
  });
</script>

Because the form still has an action, it keeps working if JavaScript fails to load.

Send JSON

const res = await fetch("https://api.sitebackend.com/forms/YOUR_FORM_ID", {
  method: "POST",
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: JSON.stringify({ email: "[email protected]", message: "Hello!" }),
});
const { ok, id, error } = await res.json();

Which errors should I handle?

StatuserrorSuggested message
400Captcha verification failedAsk the visitor to complete the captcha again.
403This site is not allowed to submit to this formAdd your origin in allowed origins.
429Too many submissions, try again shortlyAsk the visitor to wait a minute.
429This form has reached its monthly submission limitShow a fallback contact method.

See the endpoint reference for everything the endpoint returns.