Mailan
Sign in

Client script.

One script tag turns every plain HTML form on the page into an AJAX form: it submits with fetch, shows a status message, solves the ALTCHA challenge, passes captcha tokens and files through and follows your redirect. No dependencies, no bundler, no second external host.

Including it

The version is part of the URL. A future incompatible version ships as /client/v2/script.js, so a page pinned to v1 keeps working unchanged.

HTML

The script takes over every form whose action points at a Mailan submit endpoint — nothing else to initialise, and forms added to the page later are covered too.

Attributes on the form

Attribute Effect
data-mailan="off" Opt this one form out; it submits classically again.
data-mailan-altcha Fetch and solve an ALTCHA challenge before sending.
data-mailan-success Text shown after a successful submission.
data-mailan-error Fallback text when the request failed.
data-mailan-state Set by the script: „sending", „success" or „error". Style on it.

An element carrying data-mailan-message inside the form receives the status text. Without one the script appends a paragraph itself, so a form without any markup for it still gives feedback.

Events

Three events bubble from the form, each with the parsed response or the error in detail. That is the hook for your own analytics, a custom animation or a dialog.

JavaScript

Upload widget

A file input marked data-mailan-uploader gets a drop zone with a file list and remove buttons. Type, count and size are checked in the browser before anything is sent — the server limit stays the binding one.

HTML
Attribute Effect
accept Allowed types: extensions, mime types, wildcards like image/*.
data-max-files Maximum number of files. Above 1 the input becomes multiple.
data-max-file-size Size per file, e.g. „5MB", „500kb" or a byte count.
data-mailan-prompt Text inside the drop zone.
data-mailan-remove-label Label of the remove button.

A rejected file fires mailan:upload-rejected with the reason, so you can show it wherever it fits your design.

What it does on its own

  • Without an upload it sends urlencoded instead of multipart — smaller, and captcha verification sees the fields.
  • It disables the submit buttons while a request is in flight and releases them afterwards.
  • A redirect field is taken out of the payload and navigated to by the script, because fetch cannot read a cross-origin 303.
  • A captcha widget that is present but unsolved stops the submission with a message instead of a failed request.
  • After success the form is reset — so a second message does not repeat the first.