← Journal

A contact form with no backend

Forms · Static · UX

Static sites cannot receive a POST. That turns out to be a design prompt rather than a problem.

A contact form is the one thing a purely static site cannot do on its own. There is nothing listening. You have three honest options: hand the submission to a third-party service, put a small function in front of the static assets, or fall back to the humble mailto: link.

Fail soft, not shut

The version on this site tries the configured endpoint first and falls back to composing a mailto: link when none is set. It means the page is never broken — worst case it opens your mail client with the message already written.

ts
if (!endpoint) {
  // No form service configured — hand off to the mail client
  // with the message already composed.
  window.location.href = mailtoFor(values);
  return;
}

The form itself is styled as a source file, because that felt more honest than another rounded rectangle with a drop shadow.