This HTML contact form code generator outputs a complete page with labels, honeypot, and fetch-based JSON submit to MuxForms—or a one-line embed alternative.

Tool

HTML contact form generator

Pick fields, paste your form UUID, and copy production-ready markup.

MuxForms embed (recommended)

<div data-form-id="FORM_UUID"></div>
<script src="https://www.muxforms.com/embed.js" defer></script>

Full HTML page with fetch submit

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Contact</title>
    <style>
      form { display: grid; gap: 1rem; max-width: 28rem; }
      label { display: grid; gap: 0.35rem; font-size: 0.9rem; }
      input, textarea { padding: 0.5rem 0.65rem; font: inherit; }
      .mux-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
      button { padding: 0.6rem 1rem; cursor: pointer; }
      .status { font-size: 0.85rem; margin-top: 0.5rem; }
    </style>
  </head>
  <body>
    <h1>Contact us</h1>
    <form id="contact">
    <label>
      Name
      <input name="name" type="text" required autocomplete="name" />
    </label>
    <label>
      Email
      <input name="email" type="email" required autocomplete="email" />
    </label>
    <label>
      Message
      <textarea name="message" rows="5" required></textarea>
    </label>
    <!-- Honeypot: leave empty; hide with CSS -->
    <label class="mux-hp" aria-hidden="true">
      Leave blank
      <input type="text" name="_hp" tabindex="-1" autocomplete="off" />
    </label>
      <button type="submit">Send message</button>
      <p class="status" id="status" role="status"></p>
    </form>
    <script>
      const FORM_ID = "FORM_UUID";
      const API = "https://www.muxforms.com/api/v1/forms/" + FORM_ID;
      const form = document.getElementById("contact");
      const status = document.getElementById("status");

      form.addEventListener("submit", async (event) => {
        event.preventDefault();
        status.textContent = "Sending…";
        const data = Object.fromEntries(new FormData(form).entries());
        data["_hp"] = data["_hp"] || "";
        try {
          const schemaRes = await fetch(API);
          if (!schemaRes.ok) throw new Error("Could not load form schema (" + schemaRes.status + ")");
          const schema = await schemaRes.json();
          const token = schema.submitToken;
          if (!token) throw new Error("Missing submit token — allow your site origin on this form.");

          const res = await fetch(API + "/submit", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "X-MuxForms-Submit-Token": token,
            },
            body: JSON.stringify(data),
          });
          if (!res.ok) {
            const err = await res.json().catch(() => ({}));
            throw new Error(err.error || "Request failed (" + res.status + ")");
          }
          form.reset();
          status.textContent = "Thanks — we got your message.";
        } catch (e) {
          status.textContent = e.message || "Could not send. Check CORS allowlist and form id.";
        }
      });
    </script>
  </body>
</html>

The HTML page fetches a short-lived submit token, then POSTs JSON. Your production origin must be on the form allowlist. For field names that differ from your dashboard schema, edit the generated labels or use the embed.

Test CORS · Contact template

Common questions

Does this post to my server?
No. The sample posts JSON to MuxForms after fetching a submit token. You need a form id from your dashboard.
Embed vs custom HTML?
Embed is fewer lines and tracks dashboard styling. Custom HTML is for full control of markup and CSS.
Why did submit fail with CORS?
Add your exact site origin to the form allowlist, or use the form CORS tester tool.

Code is step one.

Allow your origin, publish the form, and read replies in one inbox.

Upgrade to Pro