A static-site contact form usually means picking a form-backend vendor (Formspree, Web3Forms, Getform, Basin, Netlify Forms) that emails you the fields. mailnix is the option where the fields land in a real inbox with spam scoring, status workflow, retention, CSV export, and one-click replies from a dashboard composer. The public submissions endpoint expects a JSON body, so a plain <form action> POST needs a six-line fetch shim. If a truly zero-JavaScript form is a hard requirement, embed the hosted mailnix form page in an iframe.
index.html
<!-- Contact form. Submissions land in your mailnix inbox with spam
scoring, owner-notification emails, and per-submission replies.
No server, no database, no build step required. -->
<form id="contact">
<label>Name <input name="name" required></label>
<label>Email <input name="email" type="email" required></label>
<label>Message <textarea name="message" required></textarea></label>
<!-- Honeypot: real visitors never fill this. Bots almost always do. -->
<input name="website" tabindex="-1" autocomplete="off"
aria-hidden="true" style="position:absolute;left:-9999px">
<button type="submit">Send</button>
</form>
<script>
// The mailnix public endpoint expects a JSON body of the shape
// { "data": { ...fields, "_mnx_ft": "<fill_time_token>" } }, which a
// plain <form action> POST cannot produce. This shim fetches the
// token, reshapes the FormData, and posts it.
const FORM_ID = "PUBLIC_ID";
const BASE = "https://api.mailnix.ch/v1/public/forms/" + FORM_ID;
document.getElementById("contact").addEventListener("submit", async (e) => {
e.preventDefault();
const form = e.target;
const fields = Object.fromEntries(new FormData(form));
if (fields.website) return; // honeypot tripped, silently drop
const def = await fetch(BASE).then((r) => r.json());
const res = await fetch(BASE + "/submissions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
data: { ...fields, _mnx_ft: def.fill_time_token },
}),
});
form.outerHTML = res.status === 201
? "<p>Thanks, we got your message.</p>"
: "<p>Something went wrong. Please email us instead.</p>";
});
</script>
<!-- Zero-JavaScript fallback: embed the hosted mailnix page in an
iframe, or link straight to it. It is a real HTML form on
forms.mailnix.ch and needs nothing from your site.
<iframe src="https://forms.mailnix.ch/f/PUBLIC_ID"
style="width:100%;height:640px;border:0"
loading="lazy"></iframe>
-->Setup, in order
Formspree, Web3Forms, Basin and friends email you the fields. mailnix keeps every submission with a spam score, a status workflow, per-form retention, CSV export, and per-submission replies.
The hosted form page at forms.mailnix.ch/f/<public_id> is a real HTML form that works with no JavaScript at all. Embed it in an iframe from a Hugo template, an Astro layout, or a plain index.html.
The invisible input in the snippet stops the lazy 80 percent of bots at zero cost. Turn on Turnstile or hCaptcha in the form's settings for the rest. Every submission is spam-scored regardless.
The endpoint is the same for plain HTML, Astro, Hugo, Eleventy, Jekyll, MkDocs, or any Jamstack framework. Paste the snippet or the iframe and ship.
Yes. Point the form at the mailnix public submissions endpoint and mailnix handles storage, spam filtering, and owner notifications. Your site stays fully static; you own zero servers and zero databases.
The mailnix endpoint expects a JSON body, so posting it directly needs the six-line fetch shim in the snippet. For a completely JavaScript-free form, embed the hosted page at forms.mailnix.ch/f/<public_id> in an iframe or link straight to it.
No. The public_id is designed to be visible in your page source. The security boundary is the Origin allowlist plus rate limits plus optional CAPTCHA.
Those three forward each submission to your email and stop. mailnix keeps a full inbox with spam scoring, status workflow, CSV export, retention, and per-submission replies, alongside the notification email. An AI assistant can also work the inbox for you through the form_* MCP tools.
Yes, to any owner notify address you have verified. Members verify with one click; external addresses use a double-opt-in link. You pick per-address between immediate, hourly digest, or daily digest. The submitter is never emailed automatically; replies to them are always a deliberate per-submission action.
EU data centres in Germany, run by LIMERION GmbH out of Liechtenstein. GDPR-ready by default.
One HTTP call to get started