Skip to content
Sign inJoin waitlist

Forms — Kalme HTML

The Contact form checks the required fields, shows a sending state, says “Thank you”, keeps what the visitor typed when something fails, and drops spam with a hidden honeypot field.

Out of the box it runs in demo mode: nothing is sent, the fields are logged in the browser console. Pick a destination before you publish.

A static site has no server of its own, so submissions go to a form service or a webhook. All of these have a free tier:

Service What it does formEndpoint
Formspree Emails you each submission https://formspree.io/f/<form id>
Web3Forms Emails you each submission, no account needed https://api.web3forms.com/submit + your key in formAccessKey
Getform, Basin Inbox, email, integrations the form’s endpoint URL
Zapier, Make, n8n, Pipedream Send submissions anywhere: Mailchimp, Google Sheets, Slack, a CRM the webhook (“catch hook”) URL
  1. Create a form at the service and copy its endpoint.
  2. Open assets/js/config.js and paste it:
    window.siteConfig = {
    formEndpoint: "https://formspree.io/f/abcdwxyz",
    formAccessKey: "", // Web3Forms only
    };
  3. Serve the folder (npx serve .), submit the Contact form, and check it arrived.
  4. Upload config.js with the site.

Each field by its name, as multipart/form-data:

Field Name Required
First Name firstName yes
Last Name lastName
Email email yes
Phone Number phone
Services (one choice) service
Message message

plus form (contact) and subject (“New contact form submission”), so you can tell the form apart if you add more.

The fields are ordinary <input> (text fields and radio buttons) and <textarea> elements inside the <form> in contact.html. Change a label or a placeholder in place; to add a field, copy an existing one and give it a new name. Add required to make one mandatory. The “Services” choices are radio buttons: copy one and change its value and its label to add a service. The service receives whatever the form contains — no settings to update.

  • Submit the form on the live site with a real address, and reply to the test.
  • The service must answer with a success status (2xx). If it doesn’t, the visitor sees “Something went wrong” and keeps what they typed — try it once by pasting a wrong endpoint into config.js on your local copy.

The honeypot stops the usual bots (a bot that fills the hidden field is shown “Thank you” and nothing is sent); the services above filter spam on their side as well. The endpoint is visible in the page source, which is how these services are designed to work. Add a line under the form linking to a Privacy Policy (the page in legal/ is a demo text — replace it with your own), and a consent checkbox if you plan to add senders to a marketing list.