Works anywhere
It's just HTML. Paste it into a static page, a React or Astro component, a Hugo template, or an embed block in Webflow, Framer, or Carrd. No library, no build step, no framework lock-in.
free tool
Pick your fields, get clean copy-paste HTML that works on any site: a static page, a framework component, or an embed block in a site builder.
The markup is free and unbranded. When you want submissions to land somewhere, point it at a mailcontact form endpoint.
the generator
Everything runs in your browser; nothing is stored or sent anywhere. Toggle the fields you want, pick how the form should behave after submit, and copy the result.
Works with any backend that accepts a form POST. Create a mailcontact project to get your own endpoint. Submissions land in your project inbox.
A few lines of vanilla JS post the form in the background and swap it for a thank-you note, so visitors stay on your page. No dependencies.
<form id="contact-form" action="https://mailcontact.app/api/forms/your-form-id" method="POST">
<div>
<label for="cf-name">Name</label>
<input id="cf-name" name="name" type="text" autocomplete="name">
</div>
<div>
<label for="cf-email">Email</label>
<input id="cf-email" name="email" type="email" autocomplete="email" required>
</div>
<div>
<label for="cf-message">Message</label>
<textarea id="cf-message" name="message" rows="5" required></textarea>
</div>
<!-- Honeypot: invisible to people, tempting to spam bots. Leave it empty. -->
<label aria-hidden="true" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;">
Leave this field empty
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off">
</label>
<button type="submit">Send</button>
</form>
<script>
(function () {
var form = document.getElementById("contact-form");
form.addEventListener("submit", function (event) {
event.preventDefault();
var button = form.querySelector('button[type="submit"]');
if (button) button.disabled = true;
fetch(form.action, {
method: "POST",
body: new FormData(form),
headers: { Accept: "application/json" }
})
.then(function (response) {
if (!response.ok) throw new Error("Request failed");
var thanks = document.createElement("p");
thanks.textContent = "Thanks! Your message has been sent.";
form.replaceWith(thanks);
})
.catch(function () {
if (button) button.disabled = false;
alert("Sorry, something went wrong. Please try again.");
});
});
})();
</script>why this markup
It's just HTML. Paste it into a static page, a React or Astro component, a Hugo template, or an embed block in Webflow, Framer, or Carrd. No library, no build step, no framework lock-in.
The markup is yours, free, no account. When you want submissions to land somewhere, create a mailcontact project and swap in your endpoint. That part takes about a minute.
Every input gets a real label, required fields are marked with the required attribute, and the spam honeypot is hidden from assistive tech. Boring, correct HTML.
faq
No. The generated markup posts to a form endpoint over HTTPS. Point the action at a mailcontact form endpoint and submissions land in your project inbox. No server code, no API route, no email service to configure. Any backend that accepts a standard form POST works too.
Yes, it is your markup. The generator outputs unstyled, semantic HTML on purpose so your site's existing CSS applies. Add classes, wrap it in your own layout, or restyle every element; nothing depends on specific class names or external stylesheets.
So you can answer. mailcontact validates the email field and shows it on the message in your inbox, so you always know who to get back to. A contact form without a sender address collects messages you cannot reply to.
Yes. Paste the generated HTML into an embed or custom-code block. The mailcontact endpoint accepts posts from any origin, so the form works from site builders exactly like it does from your own domain.
guides
One inbox per project, fed by your form and a real email address, with notifications in Discord or your inbox. Launching soon. Be the first to know.