Templates / HTML, JS

AJAX contact form (no page reload)

Sites that must stay on-page after submit with inline success/error UI.

Live preview

Preview only — does not submit. Copy the code block below for the real snippet.

Copy-paste code

contact-ajax.html
<form id="contact" class="space-y-3">
  <input type="email" name="email" required placeholder="Email" />
  <textarea name="message" required placeholder="Message"></textarea>
  <input type="text" name="_hp" tabindex="-1" autocomplete="off"
         aria-hidden="true" style="position:absolute;left:-9999px" />
  <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 (e) => {
    e.preventDefault();
    status.textContent = "Sending…";
    const body = Object.fromEntries(new FormData(form).entries());
    const res = await fetch("https://formheron.com/f/YOUR_KEY", {
      method: "POST",
      headers: { "content-type": "application/json", accept: "application/json" },
      body: JSON.stringify(body),
    });
    const data = await res.json().catch(() => ({}));
    if (res.ok) {
      status.textContent = "Sent. We will get back to you.";
      form.reset();
    } else {
      status.textContent = data.message || data.code || "Could not send.";
    }
  });
</script>

What to change

  • Replace YOUR_KEY.
  • Add your origin to the form allowlist (required for browser fetch).
  • Map codes like quota_exceeded and rate_limited to clearer copy.

Related templates