Contact form with auto-reply
The complete walkthrough – a contact form that emails you and thanks the visitor – is now the Tutorial. The steps that matter most for this recipe:
Once it works, these extras are worth a look.
Save senders as contacts
Section titled “Save senders as contacts”The Contact form gallery template already has Contact collection turned on (template
Settings → Contact collection, Collect contacts from this template) with Email
parameter email and Name parameter name. Every successfully sent message creates or
updates an entry in Contacts. Add more parameters under Extra fields, separated by commas,
to keep them with the contact too. See Contact collection.
Ask for more than a message
Section titled “Ask for more than a message”Add fields to the template on the Parameters tab, then add inputs with the same name to your
form. Form values arrive as text and Frontmail converts them to the declared type, for example:
| Parameter | Type | Form input |
|---|---|---|
topic |
enum with Allowed values sales, support, other |
<select name="topic"> |
newsletter |
boolean, Default value false |
<input type="checkbox" name="newsletter"> – checked becomes true, unchecked uses the default |
{{#if newsletter}}<p>Wants the newsletter.</p>{{/if}}Details: coercion from form data.
Show validation errors next to the fields
Section titled “Show validation errors next to the fields”When a value breaks a parameter rule (invalid email, missing required field, message too short),
the request fails with invalid_template_params
and nothing is sent. The error lists every problem, so you can show it at the right field:
try { await frontmail.sendForm(null, 'tpl_…', form);} catch (err) { form.querySelectorAll('.field-error').forEach((el) => (el.textContent = '')); for (const issue of err.details?.issues ?? []) { // e.g. <small class="field-error" data-for="email"></small> under each input const el = form.querySelector(`.field-error[data-for="${issue.param}"]`); if (el) el.textContent = issue.message; }}See Error handling.
Harden it against spam
Section titled “Harden it against spam”Allowed websites and the Turnstile CAPTCHA (Tutorial step 4) stop most abuse. For a busy public form you can also:
- turn on Block headless browsers in Security → Abuse protection,
- lower the Rate limit per IP,
- fill a Block list with addresses or domains you never want to hear from,
- add a Fallback service to the template (Settings → Delivery) so a provider outage doesn’t delay your messages.
See Bot protection.