Skip to content

Forms and waitlists

Turn on forms in Project › Forms (the Waitlist page template does it for you). From then on, any form on your site that posts to /_hostedge/forms/<name> is stored. There is no backend to write and no third-party script.

<form method="post" action="/_hostedge/forms/waitlist">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" required />
  <input name="_gotcha" tabindex="-1" autocomplete="off" hidden />
  <input type="hidden" name="_redirect" value="/thanks" />
  <button>Join the waitlist</button>
</form>

The name in the address (waitlist, contact, feedback…) creates the form on its first submission. Names use lowercase letters, digits, dashes and underscores.

Special fields#

FieldWhat it does
emailChecked for a valid address, used for waitlists and as the reply-to of notification emails
_gotchaSpam trap. Keep it hidden; submissions that fill it are dropped silently
_redirectA path on your site to send people to afterwards, e.g. /thanks. Without it they see a short thank-you page

Other fields starting with _ are ignored. Up to 50 fields of 5,000 characters each, 32 KB of text in total.

From JavaScript#

const response = await fetch('/_hostedge/forms/contact', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ email, message }),
})
// { ok: true } or { ok: false, error: '…' }

Forms only accept posts from their own site.

File uploads#

Turn on Accept file uploads under Options for all forms, then give your form enctype="multipart/form-data" and a file input:

<form method="post" action="/_hostedge/forms/apply" enctype="multipart/form-data">
  <input name="email" type="email" required />
  <input name="resume" type="file" accept=".pdf,.docx,image/*" />
  <button>Apply</button>
</form>

Each submission can carry up to 3 files of 5 MB each. HostEdge reads each file's first bytes to tell its type and accepts images (PNG, JPEG, GIF, WebP), PDFs, Word, Excel and PowerPoint files, and .txt, .csv or .md text; anything else (HTML, SVG, scripts, programs) is refused with a message. Files are stored privately, appear with their submission, and always download as files from the dashboard, never open in the browser. They are deleted with their submission, by the plan's retention, or when the form or project is deleted. Webhooks and notification emails name the files but do not include them.

Turnstile spam check#

For forms that attract bots, turn on Spam check with Turnstile. HostEdge sets up the check for your site's addresses (custom domains included, kept in step as you add them) and shows a snippet to add to your pages:

<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<!-- inside each form, before the button -->
<div class="cf-turnstile" data-sitekey="your-site-key"></div>

Most visitors never see a challenge. Submissions without a passing check are refused with a message asking to try again. With the check on, every form of the project needs the snippet, including ones sent with fetch (send the cf-turnstile-response field).

Double opt-in#

For waitlists and newsletters, turn on Ask people to confirm their email in a form's settings. Each new sign-up gets an email with a confirmation link; until they confirm, the submission shows as Unconfirmed, you are not notified and the webhook does not fire. Signing up again resends the link at most once an hour. Unconfirmed sign-ups are removed after 30 days.

The CSV export has an unsubscribe_url column. Put each person's link in the emails you send them; opening it marks them Unsubscribed in HostEdge so you can leave them out next time.

Spam and limits#

  • The _gotcha trap and known bots are answered like a person, so they learn nothing, and nothing is stored.
  • Each sender can submit 10 times per 10 minutes per project. HostEdge keeps a salted hash of the IP address for this, never the address itself.
  • Waitlists: with One entry per email on (the default), signing up twice is accepted but stored once.
PlanSubmissions per month
Free100
Starter2,000
Pro20,000
Agency100,000

When the month's submissions are used up, new ones are refused until the 1st or until you upgrade. Stored submissions are never deleted for that.

Notifications and integrations#

Each submission is emailed to everyone with the Developer role or above, or to the addresses you list in the form's settings. Reply to the email to answer the sender.

To send submissions to Zapier, Make, Slack or your own code, add a webhook in Settings › Webhooks with the form.submitted event. The payload includes the project, the form and every field.

Reading and exporting#

Click a form to see its submissions, newest first, with a search across all fields. Export CSV downloads every submission; cells that start with =, +, - or @ are prefixed with ' so spreadsheets never run them as formulas. Developers and above can read submissions; viewers see only the list of forms.

Submissions are kept for 90 days on Free, 1 year on Starter, 2 years on Pro and 3 years on Agency; older ones are deleted each night. Export them first if you need them longer.

View this page as MarkdownAll docs as one file